diff libervia/backend/plugins/plugin_xep_0176.py @ 4275:29fda1340078

plugin XEP-0176: Send ICE candidates buffer for initiator: - ICE buffer is now sent also for initiator. - If `ice_candidates_new_cb` is set in `session`, it will be used instead of using the `ice_candidates_new` signal. This is useful to handle internally the workflow, and will be used in incoming `Conferences` component. rel 445
author Goffi <goffi@goffi.org>
date Fri, 05 Jul 2024 17:18:32 +0200
parents 0d7bb4df2343
children 4837ec911c43
line wrap: on
line diff
--- a/libervia/backend/plugins/plugin_xep_0176.py	Fri Jul 05 16:27:52 2024 +0200
+++ b/libervia/backend/plugins/plugin_xep_0176.py	Fri Jul 05 17:18:32 2024 +0200
@@ -230,6 +230,50 @@
         ice_data = transport_data["local_ice_data"]
         return self.build_transport(ice_data)
 
+    async def _send_ice_buffer(
+        self,
+        client: SatXMPPEntity,
+        session: dict,
+        content_name: str,
+        content_data: dict,
+    ) -> None:
+        """Send ``transport-info`` actions with buffered ICE candidates.
+
+        @param client: Libervia client instance.
+        @param session: Jingle session.
+        @param content_name: Name (ID) of the content.
+        @param content_data: Data of the content.
+        @param media_type: Type of media of the content.
+        """
+        media_type = content_data["application_data"].get("media")
+        # we check if we have any buffered ICE candidates, and send them if it's the case
+        try:
+            buffer = session["XEP-0176_ice_buffer"]
+            buffered_ice_data = buffer.pop(media_type)
+        except KeyError:
+            pass
+        else:
+            if not buffer:
+                del session["XEP-0176_ice_buffer"]
+            transport_elt = self.build_transport(buffered_ice_data)
+            iq_elt, __ = self._j.build_action(
+                client,
+                self._j.A_TRANSPORT_INFO,
+                session,
+                content_name,
+                context_elt=transport_elt,
+            )
+            self.host.trigger.point(
+                "XEP-0176_jingle_handler_send_buffer",
+                client,
+                session,
+                content_name,
+                content_data,
+                transport_elt,
+                iq_elt,
+            )
+            await iq_elt.send()
+
     async def jingle_handler(
         self,
         client: SatXMPPEntity,
@@ -261,39 +305,12 @@
                 log.debug("replaying buffered events")
                 for args in buffer:
                     await self.jingle_handler(*args)
+            await self._send_ice_buffer(client, session, content_name, content_data)
         elif action == self._j.A_PREPARE_RESPONDER:
             pass
 
         elif action == self._j.A_SESSION_ACCEPT:
-            # we check if we have any buffered ICE candidates, and send them if it's the
-            # case
-            media_type = content_data["application_data"].get("media")
-            try:
-                buffer = session["XEP-0176_buffer"]
-                buffered_ice_data = buffer.pop(media_type)
-            except KeyError:
-                pass
-            else:
-                if not buffer:
-                    del session["XEP-0176_buffer"]
-                transport_elt = self.build_transport(buffered_ice_data)
-                iq_elt, __ = self._j.build_action(
-                    client,
-                    self._j.A_TRANSPORT_INFO,
-                    session,
-                    content_name,
-                    context_elt=transport_elt,
-                )
-                self.host.trigger.point(
-                    "XEP-0176_jingle_handler_send_buffer",
-                    client,
-                    session,
-                    content_name,
-                    content_data,
-                    transport_elt,
-                    iq_elt,
-                )
-                await iq_elt.send()
+            await self._send_ice_buffer(client, session, content_name, content_data)
 
         elif action == self._j.A_START:
             pass
@@ -320,11 +337,16 @@
                 )
                 self.host.bridge.ice_restart(session["id"], "peer", client.profile)
 
-            self.host.bridge.ice_candidates_new(
-                session["id"],
-                data_format.serialise({media_type: new_ice_data}),
-                client.profile,
-            )
+            ice_candidates_new_cb = session.get("ice_candidates_new_cb")
+            ice_candidates_data = {media_type: new_ice_data}
+            if ice_candidates_new_cb is None:
+                self.host.bridge.ice_candidates_new(
+                    session["id"],
+                    data_format.serialise(ice_candidates_data),
+                    client.profile,
+                )
+            else:
+                ice_candidates_new_cb(client, session, ice_candidates_data)
         elif action == self._j.A_DESTROY:
             pass
         else:
@@ -371,7 +393,7 @@
         return False
 
     async def ice_candidates_add(
-        self, client: SatXMPPEntity, session_id: str, media_ice_data: Dict[str, dict]
+        self, client: SatXMPPEntity, session_id: str, media_ice_data: dict[str, dict]
     ) -> None:
         """Called when a new ICE candidates are available for a session
 
@@ -387,7 +409,7 @@
         for media_type, new_ice_data in media_ice_data.items():
             if session["state"] == self._j.STATE_PENDING:
                 log.debug(f"session not active, buffering")
-                buffer = session.setdefault("XEP-0176_buffer", {})
+                buffer = session.setdefault("XEP-0176_ice_buffer", {})
                 media_buffer = buffer.setdefault(media_type, {})
 
                 for key in ["ufrag", "pwd"]: