summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/osmocom/gsm/gsm0808_utils.h2
-rw-r--r--src/gsm/gsm0808_utils.c54
-rw-r--r--src/gsm/libosmogsm.map1
3 files changed, 57 insertions, 0 deletions
diff --git a/include/osmocom/gsm/gsm0808_utils.h b/include/osmocom/gsm/gsm0808_utils.h
index b5106447..cb53e0c0 100644
--- a/include/osmocom/gsm/gsm0808_utils.h
+++ b/include/osmocom/gsm/gsm0808_utils.h
@@ -73,3 +73,5 @@ int gsm0808_dec_cell_id_list(struct gsm0808_cell_id_list *cil,
const uint8_t *elem, uint8_t len);
int gsm0808_chan_type_to_speech_code(uint8_t perm_spch);
+int gsm0808_speech_codec_from_chan_type(struct gsm0808_speech_codec *sc,
+ uint8_t perm_spch);
diff --git a/src/gsm/gsm0808_utils.c b/src/gsm/gsm0808_utils.c
index 64ffec4e..00da04b0 100644
--- a/src/gsm/gsm0808_utils.c
+++ b/src/gsm/gsm0808_utils.c
@@ -682,4 +682,58 @@ int gsm0808_chan_type_to_speech_codec(uint8_t perm_spch)
return -EINVAL;
}
+/*! \brief Extrapolate a speech codec field from a given permitted speech
+ * parameter (channel type).
+ * \param[out] sc Caller provided memory to store the resulting speech codec
+ * \param[in] perm_spch value that is used to derive the speech codec info
+ * (see also: enum gsm0808_speech_codec_type in gsm0808_utils.h)
+ * \returns zero when successful; negative on error */
+int gsm0808_speech_codec_from_chan_type(struct gsm0808_speech_codec *sc,
+ uint8_t perm_spch)
+{
+ int rc;
+
+ memset(sc, 0, sizeof(*sc));
+
+ /* Determine codec type */
+ rc = gsm0808_chan_type_to_speech_codec(perm_spch);
+ if (rc < 0)
+ return -EINVAL;
+ sc->type = (uint8_t) rc;
+
+ /* Depending on the speech codec type, pick a default codec
+ * configuration that exactly matches the configuration on the
+ * air interface. */
+ switch (sc->type) {
+ case GSM0808_SCT_FR3:
+ sc->cfg = GSM0808_SC_CFG_DEFAULT_FR_AMR;
+ break;
+ case GSM0808_SCT_FR4:
+ sc->cfg = GSM0808_SC_CFG_DEFAULT_OFR_AMR_WB;
+ break;
+ case GSM0808_SCT_FR5:
+ sc->cfg = GSM0808_SC_CFG_DEFAULT_FR_AMR_WB;
+ break;
+ case GSM0808_SCT_HR3:
+ sc->cfg = GSM0808_SC_CFG_DEFAULT_HR_AMR;
+ break;
+ case GSM0808_SCT_HR4:
+ sc->cfg = GSM0808_SC_CFG_DEFAULT_OHR_AMR_WB;
+ break;
+ case GSM0808_SCT_HR6:
+ sc->cfg = GSM0808_SC_CFG_DEFAULT_OHR_AMR;
+ break;
+ default:
+ /* Note: Not all codec types specify a default setting,
+ * in this case, we just set the field to zero. */
+ sc->cfg = 0;
+ }
+
+ /* Tag all codecs as "Full IP"
+ * (see als 3GPP TS 48.008 3.2.2.103) */
+ sc->fi = true;
+
+ return 0;
+}
+
/*! @} */
diff --git a/src/gsm/libosmogsm.map b/src/gsm/libosmogsm.map
index ccc5b9a4..36cba391 100644
--- a/src/gsm/libosmogsm.map
+++ b/src/gsm/libosmogsm.map
@@ -163,6 +163,7 @@ gsm0808_dec_encrypt_info;
gsm0808_enc_cell_id_list;
gsm0808_dec_cell_id_list;
gsm0808_convert_to_speech_codec_type;
+gsm0808_extrapolate_speech_codec;
gsm0858_rsl_ul_meas_enc;