# HG changeset patch # User Goffi # Date 1720192712 -7200 # Node ID 29fda1340078f2e66d2bb80825585163d70cb972 # Parent 2992f9d1e039bf4ca64afdbd1f6243c3553f6832 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 diff -r 2992f9d1e039 -r 29fda1340078 libervia/backend/plugins/plugin_xep_0176.py --- 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"]: