aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/osmocom/msc/codec_sdp_cc_t9n.h3
-rw-r--r--src/libmsc/codec_sdp_cc_t9n.c56
2 files changed, 59 insertions, 0 deletions
diff --git a/include/osmocom/msc/codec_sdp_cc_t9n.h b/include/osmocom/msc/codec_sdp_cc_t9n.h
index 8f91c788b..8993eb291 100644
--- a/include/osmocom/msc/codec_sdp_cc_t9n.h
+++ b/include/osmocom/msc/codec_sdp_cc_t9n.h
@@ -50,6 +50,9 @@ const struct codec_mapping *codec_mapping_by_perm_speech(enum gsm0808_permitted_
const struct codec_mapping *codec_mapping_by_subtype_name(const char *subtype_name);
const struct codec_mapping *codec_mapping_by_mgcp_codec(enum mgcp_codecs mgcp);
+int amr_fmtp_from_gsm0808_speech_codec(char *buf, size_t buflen, const struct gsm0808_speech_codec *sc);
+int amr_fmtp_to_gsm0808_speech_codec(struct gsm0808_speech_codec *sc, const char *fmtp);
+
int bearer_cap_add_speech_ver(struct gsm_mncc_bearer_cap *bearer_cap, enum gsm48_bcap_speech_ver speech_ver);
int sdp_audio_codec_add_to_bearer_cap(struct gsm_mncc_bearer_cap *bearer_cap, const struct sdp_audio_codec *codec);
int sdp_audio_codecs_to_bearer_cap(struct gsm_mncc_bearer_cap *bearer_cap, const struct sdp_audio_codecs *ac);
diff --git a/src/libmsc/codec_sdp_cc_t9n.c b/src/libmsc/codec_sdp_cc_t9n.c
index 790202c0e..aa83112b9 100644
--- a/src/libmsc/codec_sdp_cc_t9n.c
+++ b/src/libmsc/codec_sdp_cc_t9n.c
@@ -284,6 +284,62 @@ const struct codec_mapping *codec_mapping_by_mgcp_codec(enum mgcp_codecs mgcp)
return NULL;
}
+/* Return a bitmask of active AMR rates given the speec codec config nr, i.e. the column nr in 3GPP TS 28.062, Table
+ * 7.11.3.1.3-2, a.k.a. S0-S15. The full_rate flag is needed because config nr 1 is special: it includes 12.2k on FR but
+ * excludes it on HR. Iff full_rate == true, 12.2k is included for sc_cfg_nr == 1. */
+uint8_t amr_rates_from_speech_codec_cfg_nr(uint8_t sc_cfg_nr, bool full_rate)
+{
+#define B(BIT) (1 << (BIT))
+#define RATE_4_75 B(0)
+#define RATE_5_15 B(1)
+#define RATE_5_90 B(2)
+#define RATE_6_70 B(3)
+#define RATE_7_40 B(4)
+#define RATE_7_95 B(5)
+#define RATE_10_2 B(6)
+#define RATE_12_2 B(7)
+ static const uint8_t _amr_rates_from_speech_codec_cfg_nr[] = {
+ [0] = RATE_4_75,
+ [1] = RATE_4_75 | RATE_5_90 | RATE_7_40 | RATE_12_2,
+ [2] = RATE_5_90,
+ [3] = RATE_6_70,
+ [4] = RATE_7_40,
+ [5] = RATE_7_95,
+ [6] = RATE_10_2,
+ [7] = RATE_12_2,
+ [8] = RATE_4_75 | RATE_5_90,
+ [9] = RATE_4_75 | RATE_5_90 | RATE_6_70,
+ [10] = RATE_4_75 | RATE_5_90 | RATE_6_70 | RATE_7_40,
+ [11] = RATE_4_75 | RATE_5_90 | RATE_6_70 | RATE_7_40,
+ [12] = RATE_4_75 | RATE_5_90 | RATE_6_70 | RATE_10_2,
+ [13] = RATE_4_75 | RATE_5_90 | RATE_6_70 | RATE_10_2,
+ [14] = RATE_4_75 | RATE_5_90 | RATE_7_95 | RATE_12_2,
+ [15] = RATE_4_75 | RATE_5_90 | RATE_7_95 | RATE_12_2,
+ };
+ uint8_t ret;
+ OSMO_ASSERT(sc_cfg_nr < ARRAY_SIZE(_amr_rates_from_speech_codec_cfg_nr));
+ ret = _amr_rates_from_speech_codec_cfg_nr[sc_cfg_nr];
+ if (!full_rate && sc_cfg_nr == 1)
+ ret &= ~RATE_12_2;
+ return ret;
+}
+
+int amr_fmtp_from_gsm0808_speech_codec(char *buf, size_t buflen, const struct gsm0808_speech_codec *sc)
+{
+ struct osmo_strbuf sb = { .buf = buf, .len = buflen };
+
+ /* 3GPP TS 26.103 says "The bandwidth efficient mode of RFC 4867 shall be used. To offer the bandwidth-efficient
+ * mode, the octet-align parameter should be omitted in SDP." So never include 'octet-align=1'.
+ */
+
+ /* Accumulate rates that are allowed by the cfg bits */
+ uint8_t mode_sets = 0;
+}
+
+int amr_fmtp_to_gsm0808_speech_codec(struct gsm0808_speech_codec *sc, const char *fmtp)
+{
+}
+
/* Append given Speech Version to the end of the Bearer Capabilities Speech Version array. Return 1 if added, zero
* otherwise (as in, return the number of items added). */
int bearer_cap_add_speech_ver(struct gsm_mncc_bearer_cap *bearer_cap, enum gsm48_bcap_speech_ver speech_ver)