aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNeels Hofmeyr <nhofmeyr@sysmocom.de>2024-01-19 06:21:07 +0100
committerNeels Hofmeyr <nhofmeyr@sysmocom.de>2024-02-09 05:17:39 +0100
commitbd69253e6d84be3ad4ca33f6f02023397ec45398 (patch)
treee98d5d91f6b741c421b93539702d026306c5013f
parent7b3e3df35335449d6098e5382dce128eda2efefa (diff)
codec_mapping: add all AMR variants
-rw-r--r--src/libmsc/codec_mapping.c164
-rw-r--r--tests/msc_vlr/msc_vlr_test_call.c14
2 files changed, 130 insertions, 48 deletions
diff --git a/src/libmsc/codec_mapping.c b/src/libmsc/codec_mapping.c
index 31ee8dcb3..e87a8f8ea 100644
--- a/src/libmsc/codec_mapping.c
+++ b/src/libmsc/codec_mapping.c
@@ -30,7 +30,9 @@
#include <osmocom/msc/codec_mapping.h>
#include <osmocom/msc/mncc.h>
-const struct codec_mapping codec_map[] = {
+#define S(N) (1 << (N))
+
+static const struct codec_mapping codec_map[] = {
/* FIXME: sdp.fmtp handling is not done properly yet, proper mode-set and octet-align handling will follow in
* separate patches. */
{
@@ -111,51 +113,121 @@ const struct codec_mapping codec_map[] = {
.perm_speech = GSM0808_PERM_HR1,
.frhr = CODEC_FRHR_HR,
},
- {
- .sdp = {
- /* 112 is just what we use by default. The other call leg may impose a different number. */
- .payload_type = 112,
- .subtype_name = "AMR",
- .rate = 8000,
- /* AMR is always octet-aligned in 2G and 3G RAN, so this fmtp is signalled to remote call legs.
- * So far, fmtp is ignored in incoming SIP SDP, so an incoming SDP without 'octet-align=1' will
- * match with this entry; we will still reply with 'octet-align=1', which often works out. */
- .fmtp = OSMO_SDP_VAL_AMR_OCTET_ALIGN_1,
- },
- .mgcp = CODEC_AMR_8000_1,
- .speech_ver_count = 1,
- .speech_ver = { GSM48_BCAP_SV_AMR_F },
- .mncc_payload_msg_type = GSM_TCH_FRAME_AMR,
- .has_gsm0808_speech_codec = true,
- .gsm0808_speech_codec = {
- .fi = true,
- .type = GSM0808_SCT_FR3,
- .cfg = GSM0808_SC_CFG_DEFAULT_FR_AMR,
- },
- .perm_speech = GSM0808_PERM_FR3,
- .frhr = CODEC_FRHR_FR,
- },
- {
- /* Another entry like the above, to map HR3 to AMR, too. */
- .sdp = {
- .payload_type = 112,
- .subtype_name = "AMR",
- .rate = 8000,
- .fmtp = OSMO_SDP_VAL_AMR_OCTET_ALIGN_1,
- },
- .mgcp = CODEC_AMR_8000_1,
- .speech_ver_count = 1,
- .speech_ver = { GSM48_BCAP_SV_AMR_H },
- .mncc_payload_msg_type = GSM_TCH_FRAME_AMR,
- .has_gsm0808_speech_codec = true,
- .gsm0808_speech_codec = {
- .fi = true,
- .type = GSM0808_SCT_HR3,
- .cfg = GSM0808_SC_CFG_DEFAULT_HR_AMR,
- },
- .perm_speech = GSM0808_PERM_HR3,
- .frhr = CODEC_FRHR_HR,
- },
+
+/* payload_type = 112 is just what we use by default. The other call leg may impose a different number. */
+#define AMR_FR(IS_OA, FMTP, SPEECH_CODEC_CFG) \
+ { \
+ .sdp = { \
+ .payload_type = 112, \
+ .subtype_name = "AMR", \
+ .rate = 8000, \
+ .fmtp = FMTP, \
+ }, \
+ .mgcp = CODEC_AMR_8000_1, \
+ .speech_ver_count = 1, \
+ .speech_ver = { GSM48_BCAP_SV_AMR_F }, \
+ .mncc_payload_msg_type = GSM_TCH_FRAME_AMR, \
+ .has_gsm0808_speech_codec = true, \
+ .gsm0808_speech_codec = { \
+ .fi = true, \
+ .type = GSM0808_SCT_FR3, \
+ .cfg = SPEECH_CODEC_CFG, \
+ }, \
+ .perm_speech = GSM0808_PERM_FR3, \
+ .frhr = CODEC_FRHR_FR, \
+ }
+
+#define AMR_HR(IS_OA, FMTP, SPEECH_CODEC_CFG) \
+ { \
+ .sdp = { \
+ .payload_type = 112, \
+ .subtype_name = "AMR", \
+ .rate = 8000, \
+ .fmtp = FMTP, \
+ }, \
+ .mgcp = CODEC_AMR_8000_1, \
+ .speech_ver_count = 1, \
+ .speech_ver = { GSM48_BCAP_SV_AMR_H }, \
+ .mncc_payload_msg_type = GSM_TCH_FRAME_AMR, \
+ .has_gsm0808_speech_codec = true, \
+ .gsm0808_speech_codec = { \
+ .fi = true, \
+ .type = GSM0808_SCT_HR3, \
+ .cfg = SPEECH_CODEC_CFG, \
+ }, \
+ .perm_speech = GSM0808_PERM_HR3, \
+ .frhr = CODEC_FRHR_HR, \
+ }
+
+ /* AMR rates as in 3GPP TS 28.062, Table 7.11.3.1.3-2; gsm0808_speech_codec.cfg is a bitmask of Sn bits:
+ *
+ * S0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
+ * 12,20 (x) x x x
+ * 10,20 x x x
+ * 7,95 x x x
+ * 7,40 x x x x
+ * 6,70 x x x x x x
+ * 5,90 x x x x x x x x x x
+ * 5,15
+ * 4,75 x x x x x x x x x x
+ *
+ * OM F F F F F F F F F F F A F A F A
+ *
+ * HR Y Y Y Y Y Y Y Y Y
+ * FR Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y
+ */
+
+#if 0
+
+/* Add *all* AMR rate combinations as separate entries to the codec mapping */
+#define ALL_AMR(IS_OA, FMTP_PREFIX) \
+ /* FR rates */ \
+ AMR_FR(IS_OA, FMTP_PREFIX "mode-set=0", S(0)), \
+ AMR_FR(IS_OA, FMTP_PREFIX "mode-set=0,2,4,7", S(1)), \
+ AMR_FR(IS_OA, FMTP_PREFIX "mode-set=2", S(2)), \
+ AMR_FR(IS_OA, FMTP_PREFIX "mode-set=3", S(3)), \
+ AMR_FR(IS_OA, FMTP_PREFIX "mode-set=4", S(4)), \
+ AMR_FR(IS_OA, FMTP_PREFIX "mode-set=5", S(5)), \
+ AMR_FR(IS_OA, FMTP_PREFIX "mode-set=6", S(6)), \
+ AMR_FR(IS_OA, FMTP_PREFIX "mode-set=7", S(7)), \
+ AMR_FR(IS_OA, FMTP_PREFIX "mode-set=0,2", S(8)), \
+ AMR_FR(IS_OA, FMTP_PREFIX "mode-set=0,2,3", S(9)), \
+ AMR_FR(IS_OA, FMTP_PREFIX "mode-set=0,2,3,4", S(10)), \
+ AMR_FR(IS_OA, FMTP_PREFIX "mode-set=0,2,3,6", S(12)), \
+ AMR_FR(IS_OA, FMTP_PREFIX "mode-set=0,2,5,7", S(14)), \
+ /* AMR FR: S1 in compatibility with AMR-HR = without 12k2 */ \
+ AMR_FR(IS_OA, FMTP_PREFIX "mode-set=0,2,4", S(1)), \
+ \
+ /* HR rates */ \
+ AMR_HR(IS_OA, FMTP_PREFIX "mode-set=0", S(0)), \
+ AMR_HR(IS_OA, FMTP_PREFIX "mode-set=0,2,4", S(1)), \
+ AMR_HR(IS_OA, FMTP_PREFIX "mode-set=2", S(2)), \
+ AMR_HR(IS_OA, FMTP_PREFIX "mode-set=3", S(3)), \
+ AMR_HR(IS_OA, FMTP_PREFIX "mode-set=4", S(4)), \
+ AMR_HR(IS_OA, FMTP_PREFIX "mode-set=5", S(5)), \
+ AMR_HR(IS_OA, FMTP_PREFIX "mode-set=0,2", S(8)), \
+ AMR_HR(IS_OA, FMTP_PREFIX "mode-set=0,2,3", S(9)), \
+ AMR_HR(IS_OA, FMTP_PREFIX "mode-set=0,2,3,4", S(10))
+
+#else
+
+/* Add only AMR rates for S1 (0,2,4,7) as well as 12k2 only. */
+#define ALL_AMR(IS_OA, FMTP_PREFIX) \
+ /* FR rates */ \
+ AMR_FR(IS_OA, FMTP_PREFIX "mode-set=0,2,4,7", S(1)), \
+ AMR_FR(IS_OA, FMTP_PREFIX "mode-set=7", S(7)), \
+ AMR_FR(IS_OA, FMTP_PREFIX "mode-set=0,2,4", S(1)), \
+ \
+ /* HR rates */ \
+ AMR_HR(IS_OA, FMTP_PREFIX "mode-set=0,2,4", S(1))
+
+#endif
+
+ /* All AMR rates, once with and once without octet-align=1 */
+ ALL_AMR(true, OSMO_SDP_VAL_AMR_OCTET_ALIGN_1 ";"),
+ ALL_AMR(false, ""),
+
+ /* AMR-WB */
{
.sdp = {
.payload_type = 113,
diff --git a/tests/msc_vlr/msc_vlr_test_call.c b/tests/msc_vlr/msc_vlr_test_call.c
index 301ea8527..658b490a0 100644
--- a/tests/msc_vlr/msc_vlr_test_call.c
+++ b/tests/msc_vlr/msc_vlr_test_call.c
@@ -873,7 +873,12 @@ struct codec_test {
#define SDP_CODECS_ALL_GSM \
{ \
- "AMR:octet-align=1#112", \
+ "AMR:octet-align=1;mode-set=0,2,4,7#112", \
+ "AMR:octet-align=1;mode-set=7#114", \
+ "AMR:octet-align=1;mode-set=0,2,4#115", \
+ "AMR:mode-set=0,2,4,7#116", \
+ "AMR:mode-set=7#117", \
+ "AMR:mode-set=0,2,4#118", \
"GSM-EFR#110", \
"GSM#3", \
"GSM-HR-08#111", \
@@ -881,7 +886,12 @@ struct codec_test {
#define SDP_CODECS_ALL_GSM_WITH_ODD_PT_NRS \
{ \
- "AMR:octet-align=1#127", \
+ "AMR:octet-align=1;mode-set=0,2,4,7#127", \
+ "AMR:octet-align=1;mode-set=7#126", \
+ "AMR:octet-align=1;mode-set=0,2,4#125", \
+ "AMR:mode-set=0,2,4,7#124", \
+ "AMR:mode-set=7#123", \
+ "AMR:mode-set=0,2,4#122", \
"GSM-EFR#110", \
"GSM#3", \
"GSM-HR-08#111", \