comparison libervia/backend/plugins/plugin_xep_0167/__init__.py @ 4118:07370d2a9bde

plugin XEP-0167: keep media order when starting a call: media content order is relevant when building Jingle contents/SDP notably for bundling. This patch fixes the previous behaviour of always using the same order by keeping the order of the data (i.e. order of original SDP offer). Previous behaviour could lead to call failure. rel 424
author Goffi <goffi@goffi.org>
date Tue, 03 Oct 2023 15:15:24 +0200
parents 23fa52acf72c
children ece304ec7077
comparison
equal deleted inserted replaced
4117:d861ad696797 4118:07370d2a9bde
169 contents = [] 169 contents = []
170 metadata = call_data.get("metadata") or {} 170 metadata = call_data.get("metadata") or {}
171 171
172 if "sdp" in call_data: 172 if "sdp" in call_data:
173 sdp_data = mapping.parse_sdp(call_data["sdp"]) 173 sdp_data = mapping.parse_sdp(call_data["sdp"])
174 for media_type in ("audio", "video"): 174 to_delete = set()
175 try: 175 for media, data in sdp_data.items():
176 media_data = sdp_data.pop(media_type) 176 if media not in ("audio", "video"):
177 except KeyError:
178 continue 177 continue
178 to_delete.add(media)
179 media_type, media_data = media, data
179 call_data[media_type] = media_data["application_data"] 180 call_data[media_type] = media_data["application_data"]
180 transport_data = media_data["transport_data"] 181 transport_data = media_data["transport_data"]
181 try: 182 try:
182 call_data[media_type]["fingerprint"] = transport_data["fingerprint"] 183 call_data[media_type]["fingerprint"] = transport_data["fingerprint"]
183 except KeyError: 184 except KeyError:
194 metadata["ice-ufrag"] = transport_data["ufrag"] 195 metadata["ice-ufrag"] = transport_data["ufrag"]
195 metadata["ice-pwd"] = transport_data["pwd"] 196 metadata["ice-pwd"] = transport_data["pwd"]
196 except KeyError: 197 except KeyError:
197 log.warning("ICE data are missing from SDP") 198 log.warning("ICE data are missing from SDP")
198 continue 199 continue
200 for media in to_delete:
201 del sdp_data[media]
199 metadata.update(sdp_data.get("metadata", {})) 202 metadata.update(sdp_data.get("metadata", {}))
200 203
201 call_type = ( 204 call_type = (
202 C.META_SUBTYPE_CALL_VIDEO 205 C.META_SUBTYPE_CALL_VIDEO
203 if "video" in call_data 206 if "video" in call_data
204 else C.META_SUBTYPE_CALL_AUDIO 207 else C.META_SUBTYPE_CALL_AUDIO
205 ) 208 )
206 seen_names = set() 209 seen_names = set()
207 210
208 for media in ("audio", "video"): 211 for media, media_data in call_data.items():
209 media_data = call_data.get(media) 212 if media not in ("audio", "video"):
210 if media_data is not None: 213 continue
211 content = { 214 content = {
212 "app_ns": NS_JINGLE_RTP, 215 "app_ns": NS_JINGLE_RTP,
213 "senders": "both", 216 "senders": "both",
214 "transport_type": self._j.TRANSPORT_DATAGRAM, 217 "transport_type": self._j.TRANSPORT_DATAGRAM,
215 "app_kwargs": {"media": media, "media_data": media_data}, 218 "app_kwargs": {"media": media, "media_data": media_data},
216 "transport_data": { 219 "transport_data": {
217 "local_ice_data": { 220 "local_ice_data": {
218 "ufrag": metadata["ice-ufrag"], 221 "ufrag": metadata["ice-ufrag"],
219 "pwd": metadata["ice-pwd"], 222 "pwd": metadata["ice-pwd"],
220 "candidates": media_data.pop("ice-candidates"), 223 "candidates": media_data.pop("ice-candidates"),
221 "fingerprint": media_data.pop("fingerprint", {}), 224 "fingerprint": media_data.pop("fingerprint", {}),
222 } 225 }
223 }, 226 },
224 } 227 }
225 if "id" in media_data: 228 if "id" in media_data:
226 name = media_data.pop("id") 229 name = media_data.pop("id")
227 if name in seen_names: 230 if name in seen_names:
228 raise exceptions.DataError( 231 raise exceptions.DataError(
229 f"Content name (mid) seen multiple times: {name}" 232 f"Content name (mid) seen multiple times: {name}"
230 ) 233 )
231 content["name"] = name 234 content["name"] = name
232 contents.append(content) 235 contents.append(content)
233 if not contents: 236 if not contents:
234 raise exceptions.DataError("no valid media data found: {call_data}") 237 raise exceptions.DataError("no valid media data found: {call_data}")
235 sid = str(uuid.uuid4()) 238 sid = str(uuid.uuid4())
236 defer.ensureDeferred( 239 defer.ensureDeferred(
237 self._j.initiate( 240 self._j.initiate(