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
This commit is contained in:
Goffi 2024-07-05 17:18:32 +02:00
commit afbeeb2d1a

View file

@ -230,6 +230,50 @@ class XEP_0176(BaseTransportHandler):
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 @@ class XEP_0176(BaseTransportHandler):
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 @@ class XEP_0176(BaseTransportHandler):
)
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 @@ class XEP_0176(BaseTransportHandler):
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 @@ class XEP_0176(BaseTransportHandler):
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"]: