aboutsummaryrefslogtreecommitdiffstats
path: root/src/libmsc/msc_a.c
diff options
context:
space:
mode:
authorNeels Hofmeyr <nhofmeyr@sysmocom.de>2023-03-22 19:03:15 +0100
committerneels <nhofmeyr@sysmocom.de>2023-04-05 13:47:46 +0000
commit388d7c9374ec3ae1fd0e16bba1857ac1f789b8b4 (patch)
treee2cfac9fba1a32cc3f6b230c577b7655937c5040 /src/libmsc/msc_a.c
parent40d3c793ceb4c77116551ff0b04d2af9c61bd09b (diff)
3G: decapsulate IuUP to AMR at the MGW; allow 3G<-AMR->2G
For all 3G calls, convert IuUP <-> plain AMR/RTP on the MSC's MGW hop like this: Before this patch: hNodeB <--IuUP--> MGW@hnbgw <--IuUP--> MGW@msc <--IuUP--> other call leg After this patch: hNodeB <--IuUP--> MGW@hnbgw <--IuUP--> MGW@msc <--AMR--> other call leg ^ This allows, in principle, 2G to 3G calls without expensive transcoding, like this: hNodeB <--IuUP--> MGW@hnbgw <--IuUP--> MGW@msc <--AMR--> MGW@msc <--AMR--> MGW@bsc <--AMR--> 2G-BTS ^ (So far only proven to work with AMR-FR at 12k2.) 3G to 3G calls now look like this: hNodeB <--IuUP--> MGW@hnbgw <--IuUP--> MGW@MSC <--AMR--> MGW@MSC <--IuUP--> MGW@hnbgw <--IuUP--> hNodeB ^ Implementatino: get rid of the shim that was put in place to still send IuUP (VND.3GPP.IUFP) to the CN. So now, for all 3G voice, the IuUP gets decapsulated to plain AMR/RTP at the MSC's MGW hop. What is proven to work with this patch: successful voice call between 2G and 3G with these conditions: - a hNodeB that stubbornly accepts only 12k2 AMR; - a 2G BTS configured to use only TCH/F and only FR3, with only 12k2 as allowed AMR rate. We have not yet seen a call working for TCH/H HR3 <-> 3G, because of the lab hNodeB's limitation to 12k2. Future work we probably need: - properly request and negotiate AMR rates via SDP fmtp:mode-set. - request more RFCIs in our RANAP RAB Assignment requests (see I61e0e9e75e3239662846fd797532acdefa9f73dc). - Convert IuUP to AMR already at the HNBGW's MGW? Solving this is not part of this patch. Related: SYS#5092 Change-Id: I386a6a426c318040b019ab5541689c67e94672a1
Diffstat (limited to 'src/libmsc/msc_a.c')
-rw-r--r--src/libmsc/msc_a.c43
1 files changed, 21 insertions, 22 deletions
diff --git a/src/libmsc/msc_a.c b/src/libmsc/msc_a.c
index c022ee2d4..e8dc58b8a 100644
--- a/src/libmsc/msc_a.c
+++ b/src/libmsc/msc_a.c
@@ -1389,7 +1389,6 @@ static void msc_a_up_call_assignment_complete(struct msc_a *msc_a, const struct
struct rtp_stream *rtps_to_ran = msc_a->cc.call_leg ? msc_a->cc.call_leg->rtp[RTP_TO_RAN] : NULL;
const struct gsm0808_speech_codec *codec_if_known = ac->assignment_complete.codec_present ?
&ac->assignment_complete.codec : NULL;
- const struct codec_mapping *codec_cn;
if (!rtps_to_ran) {
LOG_MSC_A(msc_a, LOGL_ERROR, "Rx Assignment Complete, but no RTP stream is set up\n");
@@ -1408,27 +1407,27 @@ static void msc_a_up_call_assignment_complete(struct msc_a *msc_a, const struct
}
if (codec_if_known) {
- if (ac->assignment_complete.codec_with_iuup) {
- /* FUTURE: soon, we want to tell the MGW to decapsulate IuUP to plain AMR-FR/RTP. So far,
- * continue to forward IuUP to the CN.
- *
- * ran_msg_iu now returns AMR-FR as the assigned codec. If we use that directly, that will
- * instruct the MGW to decapsulate IuUP into plain RTP. Let's keep this change to an explicit
- * patch, while various codecs patches are still being applied.
- *
- * So instruct MGW to forward IuUP to CN:
- */
- codec_cn = codec_mapping_by_subtype_name("VND.3GPP.IUFP");
- OSMO_ASSERT(codec_cn);
- } else {
- codec_cn = codec_mapping_by_gsm0808_speech_codec_type(codec_if_known->type);
- /* TODO: use codec_mapping_by_gsm0808_speech_codec() to also match on codec_if_known->cfg */
- if (!codec_cn) {
- LOG_TRANS(cc_trans, LOGL_ERROR, "Unknown codec in Assignment Complete: %s\n",
- gsm0808_speech_codec_type_name(codec_if_known->type));
- call_leg_release(msc_a->cc.call_leg);
- return;
- }
+ const struct codec_mapping *codec_cn;
+ /* For 2G:
+ * - The Assignment Complete has returned a specific codec (e.g. FR3 for AMR FR).
+ * - Set this codec at the MGW endpoint facing the RAN.
+ * - Also set this codec at the MGW endpoint facing the CN -- we require an exact match on both call
+ * legs.
+ * - TODO: be aware of transcoding that the MGW is capable of, e.g. AMR octet-aligned to AMR
+ * bandwidth-efficient...
+ *
+ * For 3G:
+ * - ran_infra->force_mgw_codecs_to_ran sets VND.3GPP.IUFP as single codec at the MGW towards RAN.
+ * - ran_msg_iu.c always returns FR3 (AMR FR) for the assigned codec. Set that at the MGW towards CN.
+ * - So the MGW decapsulates IuUP <-> AMR
+ */
+ codec_cn = codec_mapping_by_gsm0808_speech_codec_type(codec_if_known->type);
+ /* TODO: use codec_mapping_by_gsm0808_speech_codec() to also match on codec_if_known->cfg */
+ if (!codec_cn) {
+ LOG_TRANS(cc_trans, LOGL_ERROR, "Unknown codec in Assignment Complete: %s\n",
+ gsm0808_speech_codec_type_name(codec_if_known->type));
+ call_leg_release(msc_a->cc.call_leg);
+ return;
}
/* Update RAN-side endpoint CI from Assignment result -- unless it is forced by the ran_infra, in which