Mercurial > libervia-backend
comparison 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 |
comparison
equal
deleted
inserted
replaced
4274:2992f9d1e039 | 4275:29fda1340078 |
---|---|
228 content_data = session["contents"][content_name] | 228 content_data = session["contents"][content_name] |
229 transport_data = content_data["transport_data"] | 229 transport_data = content_data["transport_data"] |
230 ice_data = transport_data["local_ice_data"] | 230 ice_data = transport_data["local_ice_data"] |
231 return self.build_transport(ice_data) | 231 return self.build_transport(ice_data) |
232 | 232 |
233 async def _send_ice_buffer( | |
234 self, | |
235 client: SatXMPPEntity, | |
236 session: dict, | |
237 content_name: str, | |
238 content_data: dict, | |
239 ) -> None: | |
240 """Send ``transport-info`` actions with buffered ICE candidates. | |
241 | |
242 @param client: Libervia client instance. | |
243 @param session: Jingle session. | |
244 @param content_name: Name (ID) of the content. | |
245 @param content_data: Data of the content. | |
246 @param media_type: Type of media of the content. | |
247 """ | |
248 media_type = content_data["application_data"].get("media") | |
249 # we check if we have any buffered ICE candidates, and send them if it's the case | |
250 try: | |
251 buffer = session["XEP-0176_ice_buffer"] | |
252 buffered_ice_data = buffer.pop(media_type) | |
253 except KeyError: | |
254 pass | |
255 else: | |
256 if not buffer: | |
257 del session["XEP-0176_ice_buffer"] | |
258 transport_elt = self.build_transport(buffered_ice_data) | |
259 iq_elt, __ = self._j.build_action( | |
260 client, | |
261 self._j.A_TRANSPORT_INFO, | |
262 session, | |
263 content_name, | |
264 context_elt=transport_elt, | |
265 ) | |
266 self.host.trigger.point( | |
267 "XEP-0176_jingle_handler_send_buffer", | |
268 client, | |
269 session, | |
270 content_name, | |
271 content_data, | |
272 transport_elt, | |
273 iq_elt, | |
274 ) | |
275 await iq_elt.send() | |
276 | |
233 async def jingle_handler( | 277 async def jingle_handler( |
234 self, | 278 self, |
235 client: SatXMPPEntity, | 279 client: SatXMPPEntity, |
236 action: str, | 280 action: str, |
237 session: dict, | 281 session: dict, |
259 buffer = session.pop("XEP-0176_handler_buffer", None) | 303 buffer = session.pop("XEP-0176_handler_buffer", None) |
260 if buffer: | 304 if buffer: |
261 log.debug("replaying buffered events") | 305 log.debug("replaying buffered events") |
262 for args in buffer: | 306 for args in buffer: |
263 await self.jingle_handler(*args) | 307 await self.jingle_handler(*args) |
308 await self._send_ice_buffer(client, session, content_name, content_data) | |
264 elif action == self._j.A_PREPARE_RESPONDER: | 309 elif action == self._j.A_PREPARE_RESPONDER: |
265 pass | 310 pass |
266 | 311 |
267 elif action == self._j.A_SESSION_ACCEPT: | 312 elif action == self._j.A_SESSION_ACCEPT: |
268 # we check if we have any buffered ICE candidates, and send them if it's the | 313 await self._send_ice_buffer(client, session, content_name, content_data) |
269 # case | |
270 media_type = content_data["application_data"].get("media") | |
271 try: | |
272 buffer = session["XEP-0176_buffer"] | |
273 buffered_ice_data = buffer.pop(media_type) | |
274 except KeyError: | |
275 pass | |
276 else: | |
277 if not buffer: | |
278 del session["XEP-0176_buffer"] | |
279 transport_elt = self.build_transport(buffered_ice_data) | |
280 iq_elt, __ = self._j.build_action( | |
281 client, | |
282 self._j.A_TRANSPORT_INFO, | |
283 session, | |
284 content_name, | |
285 context_elt=transport_elt, | |
286 ) | |
287 self.host.trigger.point( | |
288 "XEP-0176_jingle_handler_send_buffer", | |
289 client, | |
290 session, | |
291 content_name, | |
292 content_data, | |
293 transport_elt, | |
294 iq_elt, | |
295 ) | |
296 await iq_elt.send() | |
297 | 314 |
298 elif action == self._j.A_START: | 315 elif action == self._j.A_START: |
299 pass | 316 pass |
300 | 317 |
301 elif action == self._j.A_SESSION_INITIATE: | 318 elif action == self._j.A_SESSION_INITIATE: |
318 f"Peer ICE restart detected on session {session['id']} " | 335 f"Peer ICE restart detected on session {session['id']} " |
319 f"[{client.profile}]" | 336 f"[{client.profile}]" |
320 ) | 337 ) |
321 self.host.bridge.ice_restart(session["id"], "peer", client.profile) | 338 self.host.bridge.ice_restart(session["id"], "peer", client.profile) |
322 | 339 |
323 self.host.bridge.ice_candidates_new( | 340 ice_candidates_new_cb = session.get("ice_candidates_new_cb") |
324 session["id"], | 341 ice_candidates_data = {media_type: new_ice_data} |
325 data_format.serialise({media_type: new_ice_data}), | 342 if ice_candidates_new_cb is None: |
326 client.profile, | 343 self.host.bridge.ice_candidates_new( |
327 ) | 344 session["id"], |
345 data_format.serialise(ice_candidates_data), | |
346 client.profile, | |
347 ) | |
348 else: | |
349 ice_candidates_new_cb(client, session, ice_candidates_data) | |
328 elif action == self._j.A_DESTROY: | 350 elif action == self._j.A_DESTROY: |
329 pass | 351 pass |
330 else: | 352 else: |
331 log.warning("FIXME: unmanaged action {}".format(action)) | 353 log.warning("FIXME: unmanaged action {}".format(action)) |
332 | 354 |
369 ice_data["candidates"] = new_ice_data["candidates"] | 391 ice_data["candidates"] = new_ice_data["candidates"] |
370 return True | 392 return True |
371 return False | 393 return False |
372 | 394 |
373 async def ice_candidates_add( | 395 async def ice_candidates_add( |
374 self, client: SatXMPPEntity, session_id: str, media_ice_data: Dict[str, dict] | 396 self, client: SatXMPPEntity, session_id: str, media_ice_data: dict[str, dict] |
375 ) -> None: | 397 ) -> None: |
376 """Called when a new ICE candidates are available for a session | 398 """Called when a new ICE candidates are available for a session |
377 | 399 |
378 @param session_id: Session ID | 400 @param session_id: Session ID |
379 @param media_ice_data: a map from media type (audio, video) to ICE data | 401 @param media_ice_data: a map from media type (audio, video) to ICE data |
385 content_data: dict | None = None | 407 content_data: dict | None = None |
386 | 408 |
387 for media_type, new_ice_data in media_ice_data.items(): | 409 for media_type, new_ice_data in media_ice_data.items(): |
388 if session["state"] == self._j.STATE_PENDING: | 410 if session["state"] == self._j.STATE_PENDING: |
389 log.debug(f"session not active, buffering") | 411 log.debug(f"session not active, buffering") |
390 buffer = session.setdefault("XEP-0176_buffer", {}) | 412 buffer = session.setdefault("XEP-0176_ice_buffer", {}) |
391 media_buffer = buffer.setdefault(media_type, {}) | 413 media_buffer = buffer.setdefault(media_type, {}) |
392 | 414 |
393 for key in ["ufrag", "pwd"]: | 415 for key in ["ufrag", "pwd"]: |
394 if key not in media_buffer: | 416 if key not in media_buffer: |
395 media_buffer[key] = new_ice_data[key] | 417 media_buffer[key] = new_ice_data[key] |