Mercurial > libervia-backend
comparison libervia/backend/plugins/plugin_xep_0167/mapping.py @ 4240:79c8a70e1813
backend, frontend: prepare remote control:
This is a series of changes necessary to prepare the implementation of remote control
feature:
- XEP-0166: add a `priority` attribute to `ApplicationData`: this is needed when several
applications are working in a same session, to know which one must be handled first.
Will be used to make Remote Control have precedence over Call content.
- XEP-0166: `_call_plugins` is now async and is not used with `DeferredList` anymore: the
benefit to have methods called in parallels is very low, and it cause a lot of trouble
as we can't predict order. Methods are now called sequentially so workflow can be
predicted.
- XEP-0167: fix `senders` XMPP attribute <=> SDP mapping
- XEP-0234: preflight acceptance key is now `pre-accepted` instead of `file-accepted`, so
the same key can be used with other jingle applications.
- XEP-0167, XEP-0343: move some method to XEP-0167
- XEP-0353: use new `priority` feature to call preflight methods of applications according
to it.
- frontend (webrtc): refactor the sources/sink handling with a more flexible mechanism
based on Pydantic models. It is now possible to have has many Data Channel as necessary,
to have them in addition to A/V streams, to specify manually GStreamer sources and
sinks, etc.
- frontend (webrtc): rework of the pipeline to reduce latency.
- frontend: new `portal_desktop` method. Screenshare portal handling has been moved there,
and RemoteDesktop portal has been added.
- frontend (webrtc): fix `extract_ufrag_pwd` method.
rel 436
author | Goffi <goffi@goffi.org> |
---|---|
date | Sat, 11 May 2024 13:52:41 +0200 |
parents | e11b13418ba6 |
children | 0d7bb4df2343 |
comparison
equal
deleted
inserted
replaced
4239:a38559e6d6e2 | 4240:79c8a70e1813 |
---|---|
35 """Returns appropriate SDP attribute corresponding to Jingle senders attribute""" | 35 """Returns appropriate SDP attribute corresponding to Jingle senders attribute""" |
36 if senders == "both": | 36 if senders == "both": |
37 return "a=sendrecv" | 37 return "a=sendrecv" |
38 elif senders == "none": | 38 elif senders == "none": |
39 return "a=inactive" | 39 return "a=inactive" |
40 elif session["role"] == senders: | 40 elif session["role"] != senders: |
41 return "a=sendonly" | 41 return "a=sendonly" |
42 else: | 42 else: |
43 return "a=recvonly" | 43 return "a=recvonly" |
44 | 44 |
45 | 45 |
111 session, | 111 session, |
112 local, | 112 local, |
113 sdp_lines, | 113 sdp_lines, |
114 triggers_no_cancel=True | 114 triggers_no_cancel=True |
115 ) | 115 ) |
116 | 116 content_names = sorted(contents) |
117 for content_name, content_data in contents.items(): | 117 |
118 for content_name, content_data in [(n, contents[n]) for n in content_names]: # contents.items(): | |
118 app_data_key = "local_data" if local else "peer_data" | 119 app_data_key = "local_data" if local else "peer_data" |
119 application_data = content_data["application_data"] | 120 application_data = content_data["application_data"] |
120 media_data = application_data[app_data_key] | 121 media_data = application_data[app_data_key] |
121 media = application_data["media"] | 122 media = application_data["media"] |
122 payload_types = media_data.get("payload_types", {}) | 123 payload_types = media_data.get("payload_types", {}) |
239 | 240 |
240 # Combine SDP lines and return the result | 241 # Combine SDP lines and return the result |
241 return "\r\n".join(sdp_lines) + "\r\n" | 242 return "\r\n".join(sdp_lines) + "\r\n" |
242 | 243 |
243 | 244 |
244 def parse_sdp(sdp: str) -> dict: | 245 def parse_sdp(sdp: str, role: str) -> dict: |
245 """Parse SDP string. | 246 """Parse SDP string. |
246 | 247 |
247 @param sdp: The SDP string to parse. | 248 @param sdp: The SDP string to parse. |
248 | 249 @param role: Role of the entities which produces the SDP. |
249 @return: A dictionary containing parsed session data. | 250 @return: A dictionary containing parsed session data. |
250 """ | 251 """ |
251 # FIXME: to be removed once host is accessible from global var | 252 # FIXME: to be removed once host is accessible from global var |
252 assert host is not None | 253 assert host is not None |
253 lines = sdp.strip().split("\r\n") | 254 lines = sdp.strip().split("\r\n") |
261 transport_data: Optional[Dict[str, Any]] = None | 262 transport_data: Optional[Dict[str, Any]] = None |
262 fingerprint_data: Optional[Dict[str, str]] = None | 263 fingerprint_data: Optional[Dict[str, str]] = None |
263 ice_pwd: Optional[str] = None | 264 ice_pwd: Optional[str] = None |
264 ice_ufrag: Optional[str] = None | 265 ice_ufrag: Optional[str] = None |
265 payload_types: Optional[Dict[int, dict]] = None | 266 payload_types: Optional[Dict[int, dict]] = None |
267 # default value, will be be modified by SDP | |
268 senders: str = "both" | |
266 | 269 |
267 for line in lines: | 270 for line in lines: |
268 try: | 271 try: |
269 parts = line.split() | 272 parts = line.split() |
270 prefix = parts[0][:2] # Extract the 'a=', 'm=', etc., prefix | 273 prefix = parts[0][:2] # Extract the 'a=', 'm=', etc., prefix |
293 if ice_ufrag is not None: | 296 if ice_ufrag is not None: |
294 transport_data["ufrag"] = ice_ufrag | 297 transport_data["ufrag"] = ice_ufrag |
295 media_data = call_data[media_type] = { | 298 media_data = call_data[media_type] = { |
296 "application_data": application_data, | 299 "application_data": application_data, |
297 "transport_data": transport_data, | 300 "transport_data": transport_data, |
301 "senders": senders | |
298 } | 302 } |
299 | 303 |
300 elif prefix == "a=": | 304 elif prefix == "a=": |
301 if ":" in parts[0]: | 305 if ":" in parts[0]: |
302 attribute, parts[0] = parts[0].split(":", 1) | 306 attribute, parts[0] = parts[0].split(":", 1) |
424 | 428 |
425 elif attribute == "ice-pwd": | 429 elif attribute == "ice-pwd": |
426 if transport_data is not None: | 430 if transport_data is not None: |
427 transport_data["pwd"] = parts[0] | 431 transport_data["pwd"] = parts[0] |
428 | 432 |
433 elif attribute in ("sendrecv", "sendonly", "recvonly", "inactive"): | |
434 if attribute == "sendrecv": | |
435 value = "both" | |
436 elif attribute == "sendonly": | |
437 value = role | |
438 elif attribute == "recvonly": | |
439 value = "responder" if role == "initiator" else "initiator" | |
440 else: | |
441 value = "none" | |
442 | |
443 if application_data is None: | |
444 # this is a global value, we use is as new default value | |
445 senders = value | |
446 else: | |
447 # this is a media specific value, it will replace the one used as | |
448 # default for this media | |
449 application_data["senders"] = value | |
450 | |
429 host.trigger.point( | 451 host.trigger.point( |
430 "XEP-0167_parse_sdp_a", | 452 "XEP-0167_parse_sdp_a", |
431 attribute, | 453 attribute, |
432 parts, | 454 parts, |
433 call_data, | 455 call_data, |