changeset 4118:07370d2a9bde

plugin XEP-0167: keep media order when starting a call: media content order is relevant when building Jingle contents/SDP notably for bundling. This patch fixes the previous behaviour of always using the same order by keeping the order of the data (i.e. order of original SDP offer). Previous behaviour could lead to call failure. rel 424
author Goffi <goffi@goffi.org>
date Tue, 03 Oct 2023 15:15:24 +0200
parents d861ad696797
children ece304ec7077
files libervia/backend/plugins/plugin_xep_0167/__init__.py
diffstat 1 files changed, 32 insertions(+), 29 deletions(-) [+]
line wrap: on
line diff
--- a/libervia/backend/plugins/plugin_xep_0167/__init__.py	Tue Oct 03 15:03:53 2023 +0200
+++ b/libervia/backend/plugins/plugin_xep_0167/__init__.py	Tue Oct 03 15:15:24 2023 +0200
@@ -171,11 +171,12 @@
 
         if "sdp" in call_data:
             sdp_data = mapping.parse_sdp(call_data["sdp"])
-            for media_type in ("audio", "video"):
-                try:
-                    media_data = sdp_data.pop(media_type)
-                except KeyError:
+            to_delete = set()
+            for media, data in sdp_data.items():
+                if media not in ("audio", "video"):
                     continue
+                to_delete.add(media)
+                media_type, media_data = media, data
                 call_data[media_type] = media_data["application_data"]
                 transport_data = media_data["transport_data"]
                 try:
@@ -196,6 +197,8 @@
                 except KeyError:
                     log.warning("ICE data are missing from SDP")
                     continue
+            for media in to_delete:
+                del sdp_data[media]
             metadata.update(sdp_data.get("metadata", {}))
 
         call_type = (
@@ -205,31 +208,31 @@
         )
         seen_names = set()
 
-        for media in ("audio", "video"):
-            media_data = call_data.get(media)
-            if media_data is not None:
-                content = {
-                    "app_ns": NS_JINGLE_RTP,
-                    "senders": "both",
-                    "transport_type": self._j.TRANSPORT_DATAGRAM,
-                    "app_kwargs": {"media": media, "media_data": media_data},
-                    "transport_data": {
-                        "local_ice_data": {
-                            "ufrag": metadata["ice-ufrag"],
-                            "pwd": metadata["ice-pwd"],
-                            "candidates": media_data.pop("ice-candidates"),
-                            "fingerprint": media_data.pop("fingerprint", {}),
-                        }
-                    },
-                }
-                if "id" in media_data:
-                    name = media_data.pop("id")
-                    if name in seen_names:
-                        raise exceptions.DataError(
-                            f"Content name (mid) seen multiple times: {name}"
-                        )
-                    content["name"] = name
-                contents.append(content)
+        for media, media_data in call_data.items():
+            if media not in ("audio", "video"):
+                continue
+            content = {
+                "app_ns": NS_JINGLE_RTP,
+                "senders": "both",
+                "transport_type": self._j.TRANSPORT_DATAGRAM,
+                "app_kwargs": {"media": media, "media_data": media_data},
+                "transport_data": {
+                    "local_ice_data": {
+                        "ufrag": metadata["ice-ufrag"],
+                        "pwd": metadata["ice-pwd"],
+                        "candidates": media_data.pop("ice-candidates"),
+                        "fingerprint": media_data.pop("fingerprint", {}),
+                    }
+                },
+            }
+            if "id" in media_data:
+                name = media_data.pop("id")
+                if name in seen_names:
+                    raise exceptions.DataError(
+                        f"Content name (mid) seen multiple times: {name}"
+                    )
+                content["name"] = name
+            contents.append(content)
         if not contents:
             raise exceptions.DataError("no valid media data found: {call_data}")
         sid = str(uuid.uuid4())