falconia has uploaded this change for review. (
https://gerrit.osmocom.org/c/libosmocore/+/36967?usp=email )
Change subject: gsm48_ie: add helper function for speech bearer cap on GSM MS side
......................................................................
gsm48_ie: add helper function for speech bearer cap on GSM MS side
The speech version list part of TS 24.008 section 10.5.4.5 bearer
capability IE is valid only in the MS->network direction, and will
thus only need to be set by GSM MS implementations. The "natural"
input to the construction of this IE is the list of supported speech
codecs in the order of preference, but spec-compliant output requires
additional quirks:
* Radio channel requirement bits need to be set based on the v1-only
subset of the full speech version list;
* There is a curious requirement (commonly ignored by other implementors)
that the full form of the speech version list shall be elided from
the final output if only v1 codecs are supported.
Provide a helper function that finishes filling out the full
struct gsm_mncc_bearer_cap after the caller has set only the speech
version list and the CTM support flag.
Change-Id: Iaf41687da1d377e98f26e6a16d991ab7d95be0fc
---
M include/osmocom/gsm/gsm48_ie.h
M src/gsm/gsm48_ie.c
2 files changed, 92 insertions(+), 0 deletions(-)
git pull ssh://gerrit.osmocom.org:29418/libosmocore refs/changes/67/36967/1
diff --git a/include/osmocom/gsm/gsm48_ie.h b/include/osmocom/gsm/gsm48_ie.h
index 4768283..c6b3a07 100644
--- a/include/osmocom/gsm/gsm48_ie.h
+++ b/include/osmocom/gsm/gsm48_ie.h
@@ -29,6 +29,8 @@
/* encode 'bearer capability' */
int gsm48_encode_bearer_cap(struct msgb *msg, int lv_only,
const struct gsm_mncc_bearer_cap *bcap);
+/* prepare speech bearer cap on GSM MS side */
+int gsm48_ms_prepare_speech_bearer_cap(struct gsm_mncc_bearer_cap *bcap);
/* decode 'call control cap' */
int gsm48_decode_cccap(struct gsm_mncc_cccap *ccap, const uint8_t *lv);
/* encode 'call control cap' */
diff --git a/src/gsm/gsm48_ie.c b/src/gsm/gsm48_ie.c
index b95609f..b410ce4 100644
--- a/src/gsm/gsm48_ie.c
+++ b/src/gsm/gsm48_ie.c
@@ -371,6 +371,69 @@
return 0;
}
+/*! This function is meant to be called only by GSM MS implementations
+ * (not network side), and only for speech calls. The caller needs to
+ * fill in speech_ver[] and speech_ctm members of struct gsm_mncc_bearer_cap,
+ * then this function fills in the rest, producing a struct that is
+ * good to pass to gsm48_encode_bearer_cap().
+ * \param[in/out] bcap partially filled on input, completely filled on output
+ * \returns 0 on success; negative on error */
+int gsm48_ms_prepare_speech_bearer_cap(struct gsm_mncc_bearer_cap *bcap)
+{
+ int s;
+ int fr_pos = -1, hr_pos = -1;
+ bool newer_codecs = false;
+
+ bcap->transfer = GSM48_BCAP_ITCAP_SPEECH;
+ bcap->mode = GSM48_BCAP_TMOD_CIRCUIT;
+ bcap->coding = GSM48_BCAP_CODING_GSM_STD;
+
+ /* find FRv1 and HRv1 in the caller-filled speech_ver[] list */
+ for (s = 0; bcap->speech_ver[s] >= 0; s++) {
+ switch (bcap->speech_ver[s]) {
+ case GSM48_BCAP_SV_FR:
+ if (fr_pos >= 0) /* duplicates invalid */
+ return -EINVAL;
+ fr_pos = s;
+ break;
+ case GSM48_BCAP_SV_HR:
+ if (hr_pos >= 0) /* duplicates invalid */
+ return -EINVAL;
+ hr_pos = s;
+ break;
+ default:
+ newer_codecs = true;
+ break;
+ }
+ }
+ /* FRv1 support is mandatory */
+ if (fr_pos < 0)
+ return -EINVAL;
+
+ /* Radio channel req bits are for ancient GSM networks that predate
+ * the addition of octets 3a etc: they indicate the v1-only subset
+ * of the full speech version list. */
+ if (hr_pos < 0)
+ bcap->radio = GSM48_BCAP_RRQ_FR_ONLY;
+ else if (fr_pos < hr_pos)
+ bcap->radio = GSM48_BCAP_RRQ_DUAL_FR;
+ else
+ bcap->radio = GSM48_BCAP_RRQ_DUAL_HR;
+
+ /* TS 24.008 section 10.5.4.5.1 says that octets 3a etc "shall"
+ * be included only if the MS supports either CTM text telephony
+ * or at least one newer-than-v1 speech codec. Other GSM MS
+ * implementations with available source code don't follow this
+ * stipulation, probably on the reasoning that if the code
+ * implementation is new enough to know about octets 3a etc,
+ * then the product it goes into will support at least EFR
+ * if not AMR - but let's honor the word of the spec
+ * for brownie points. */
+ if (!newer_codecs && !bcap->speech_ctm)
+ bcap->speech_ver[0] = -1; /* empty list => no octet 3a */
+ return 0;
+}
+
/*! Decode TS 04.08 Call Control Capabilities IE (10.5.4.5a)
* \param[out] ccap Caller-provided memory for decoded CC capabilities
* \param[in] lv Length-Value of IE
--
To view, visit
https://gerrit.osmocom.org/c/libosmocore/+/36967?usp=email
To unsubscribe, or for help writing mail filters, visit
https://gerrit.osmocom.org/settings
Gerrit-Project: libosmocore
Gerrit-Branch: master
Gerrit-Change-Id: Iaf41687da1d377e98f26e6a16d991ab7d95be0fc
Gerrit-Change-Number: 36967
Gerrit-PatchSet: 1
Gerrit-Owner: falconia <falcon(a)freecalypso.org>
Gerrit-MessageType: newchange