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
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