Mercurial > libervia-backend
comparison libervia/backend/plugins/plugin_xep_0176.py @ 4231:e11b13418ba6
plugin XEP-0353, XEP-0234, jingle: WebRTC data channel signaling implementation:
Implement XEP-0343: Signaling WebRTC Data Channels in Jingle. The current version of the
XEP (0.3.1) has no implementation and contains some flaws. After discussing this on xsf@,
Daniel (from Conversations) mentioned that they had a sprint with Larma (from Dino) to
work on another version and provided me with this link:
https://gist.github.com/iNPUTmice/6c56f3e948cca517c5fb129016d99e74 . I have used it for my
implementation.
This implementation reuses work done on Jingle A/V call (notably XEP-0176 and XEP-0167
plugins), with adaptations. When used, XEP-0234 will not handle the file itself as it
normally does. This is because WebRTC has several implementations (browser for web
interface, GStreamer for others), and file/data must be handled directly by the frontend.
This is particularly important for web frontends, as the file is not sent from the backend
but from the end-user's browser device.
Among the changes, there are:
- XEP-0343 implementation.
- `file_send` bridge method now use serialised dict as output.
- New `BaseTransportHandler.is_usable` method which get content data and returns a boolean
(default to `True`) to tell if this transport can actually be used in this context (when
we are initiator). Used in webRTC case to see if call data are available.
- Support of `application` media type, and everything necessary to handle data channels.
- Better confirmation message, with file name, size and description when available.
- When file is accepted in preflight, it is specified in following `action_new` signal for
actual file transfer. This way, frontend can avoid the display or 2 confirmation
messages.
- XEP-0166: when not specified, default `content` name is now its index number instead of
a UUID. This follows the behaviour of browsers.
- XEP-0353: better handling of events such as call taken by another device.
- various other updates.
rel 441
author | Goffi <goffi@goffi.org> |
---|---|
date | Sat, 06 Apr 2024 12:57:23 +0200 |
parents | 23fa52acf72c |
children | 0d7bb4df2343 |
comparison
equal
deleted
inserted
replaced
4230:314d3c02bb67 | 4231:e11b13418ba6 |
---|---|
51 C.PI_DESCRIPTION: _("""Implementation of Jingle ICE-UDP transport"""), | 51 C.PI_DESCRIPTION: _("""Implementation of Jingle ICE-UDP transport"""), |
52 } | 52 } |
53 | 53 |
54 | 54 |
55 class XEP_0176(BaseTransportHandler): | 55 class XEP_0176(BaseTransportHandler): |
56 namespace = NS_JINGLE_ICE_UDP | |
57 | |
56 def __init__(self, host): | 58 def __init__(self, host): |
57 log.info(f"plugin {PLUGIN_INFO[C.PI_NAME]!r} initialization") | 59 log.info(f"plugin {PLUGIN_INFO[C.PI_NAME]!r} initialization") |
58 self.host = host | 60 self.host = host |
59 self._j = host.plugins["XEP-0166"] # shortcut to access jingle | 61 self._j = host.plugins["XEP-0166"] # shortcut to access jingle |
60 self._j.register_transport( | 62 self._j.register_transport( |
280 self._j.A_TRANSPORT_INFO, | 282 self._j.A_TRANSPORT_INFO, |
281 session, | 283 session, |
282 content_name, | 284 content_name, |
283 context_elt=transport_elt, | 285 context_elt=transport_elt, |
284 ) | 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 ) | |
285 await iq_elt.send() | 296 await iq_elt.send() |
286 | 297 |
287 elif action == self._j.A_START: | 298 elif action == self._j.A_START: |
288 pass | 299 pass |
289 | 300 |
368 @param media_ice_data: a map from media type (audio, video) to ICE data | 379 @param media_ice_data: a map from media type (audio, video) to ICE data |
369 ICE data must be in the same format as in [self.parse_transport] | 380 ICE data must be in the same format as in [self.parse_transport] |
370 """ | 381 """ |
371 session = self._j.get_session(client, session_id) | 382 session = self._j.get_session(client, session_id) |
372 iq_elt: Optional[domish.Element] = None | 383 iq_elt: Optional[domish.Element] = None |
384 content_name: str|None = None | |
385 content_data: dict|None = None | |
373 | 386 |
374 for media_type, new_ice_data in media_ice_data.items(): | 387 for media_type, new_ice_data in media_ice_data.items(): |
375 if session["state"] == self._j.STATE_PENDING: | 388 if session["state"] == self._j.STATE_PENDING: |
376 log.debug(f"session not active, buffering") | 389 log.debug(f"session not active, buffering") |
377 buffer = session.setdefault("XEP-0176_buffer", {}) | 390 buffer = session.setdefault("XEP-0176_buffer", {}) |
418 iq_elt=iq_elt, | 431 iq_elt=iq_elt, |
419 context_elt=transport_elt, | 432 context_elt=transport_elt, |
420 ) | 433 ) |
421 | 434 |
422 if iq_elt is not None: | 435 if iq_elt is not None: |
436 assert content_name is not None and content_data is not None | |
423 try: | 437 try: |
438 self.host.trigger.point( | |
439 "XEP-0176_ice_candidate_send", client, session, media_ice_data, | |
440 content_name, content_data, iq_elt | |
441 ) | |
424 await iq_elt.send() | 442 await iq_elt.send() |
425 except Exception as e: | 443 except Exception as e: |
426 log.warning(f"Could not send new ICE candidates: {e}") | 444 log.warning(f"Could not send new ICE candidates: {e}") |
427 | 445 |
428 | 446 |