| 219 g_list_free(iter); |
219 g_list_free(iter); |
| 220 |
220 |
| 221 return media; |
221 return media; |
| 222 } |
222 } |
| 223 |
223 |
| |
224 static JingleRawUdpCandidate * |
| |
225 jingle_rtp_candidate_to_rawudp(JingleSession *session, guint generation, |
| |
226 PurpleMediaCandidate *candidate) |
| |
227 { |
| |
228 gchar *id = jabber_get_next_id(jingle_session_get_js(session)); |
| |
229 JingleRawUdpCandidate *rawudp_candidate = |
| |
230 jingle_rawudp_candidate_new(id, |
| |
231 generation, candidate->component_id, |
| |
232 candidate->ip, candidate->port); |
| |
233 g_free(id); |
| |
234 return rawudp_candidate; |
| |
235 } |
| |
236 |
| |
237 static JingleIceUdpCandidate * |
| |
238 jingle_rtp_candidate_to_iceudp(JingleSession *session, guint generation, |
| |
239 PurpleMediaCandidate *candidate) |
| |
240 { |
| |
241 gchar *id = jabber_get_next_id(jingle_session_get_js(session)); |
| |
242 JingleIceUdpCandidate *iceudp_candidate = jingle_iceudp_candidate_new( |
| |
243 candidate->component_id, candidate->foundation, |
| |
244 generation, id, candidate->ip, 0, |
| |
245 candidate->port, candidate->priority, "udp", |
| |
246 candidate->type == PURPLE_MEDIA_CANDIDATE_TYPE_HOST ? "host" : |
| |
247 candidate->type == PURPLE_MEDIA_CANDIDATE_TYPE_SRFLX ? "srflx" : |
| |
248 candidate->type == PURPLE_MEDIA_CANDIDATE_TYPE_PRFLX ? "prflx" : |
| |
249 candidate->type == PURPLE_MEDIA_CANDIDATE_TYPE_RELAY ? "relay" : "", |
| |
250 candidate->username, candidate->password); |
| |
251 iceudp_candidate->reladdr = g_strdup(candidate->base_ip); |
| |
252 iceudp_candidate->relport = candidate->base_port; |
| |
253 g_free(id); |
| |
254 return iceudp_candidate; |
| |
255 } |
| |
256 |
| 224 static JingleTransport * |
257 static JingleTransport * |
| 225 jingle_rtp_candidates_to_transport(JingleSession *session, GType type, guint generation, GList *candidates) |
258 jingle_rtp_candidates_to_transport(JingleSession *session, GType type, guint generation, GList *candidates) |
| 226 { |
259 { |
| 227 if (type == JINGLE_TYPE_RAWUDP) { |
260 if (type == JINGLE_TYPE_RAWUDP) { |
| 228 JingleTransport *transport = jingle_transport_create(JINGLE_TRANSPORT_RAWUDP); |
261 JingleTransport *transport = jingle_transport_create(JINGLE_TRANSPORT_RAWUDP); |
| 229 JingleRawUdpCandidate *rawudp_candidate; |
262 JingleRawUdpCandidate *rawudp_candidate; |
| 230 for (; candidates; candidates = g_list_next(candidates)) { |
263 for (; candidates; candidates = g_list_next(candidates)) { |
| 231 PurpleMediaCandidate *candidate = candidates->data; |
264 PurpleMediaCandidate *candidate = candidates->data; |
| 232 gchar *id = jabber_get_next_id( |
265 rawudp_candidate = jingle_rtp_candidate_to_rawudp( |
| 233 jingle_session_get_js(session)); |
266 session, generation, candidate); |
| 234 rawudp_candidate = jingle_rawudp_candidate_new(id, |
267 jingle_rawudp_add_local_candidate( |
| 235 generation, candidate->component_id, |
268 JINGLE_RAWUDP(transport), |
| 236 candidate->ip, candidate->port); |
269 rawudp_candidate); |
| 237 jingle_rawudp_add_local_candidate(JINGLE_RAWUDP(transport), rawudp_candidate); |
|
| 238 g_free(id); |
|
| 239 } |
270 } |
| 240 return transport; |
271 return transport; |
| 241 } else if (type == JINGLE_TYPE_ICEUDP) { |
272 } else if (type == JINGLE_TYPE_ICEUDP) { |
| 242 JingleTransport *transport = jingle_transport_create(JINGLE_TRANSPORT_ICEUDP); |
273 JingleTransport *transport = jingle_transport_create(JINGLE_TRANSPORT_ICEUDP); |
| 243 JingleIceUdpCandidate *iceudp_candidate; |
274 JingleIceUdpCandidate *iceudp_candidate; |
| 244 for (; candidates; candidates = g_list_next(candidates)) { |
275 for (; candidates; candidates = g_list_next(candidates)) { |
| 245 PurpleMediaCandidate *candidate = candidates->data; |
276 PurpleMediaCandidate *candidate = candidates->data; |
| 246 gchar *id = jabber_get_next_id( |
277 iceudp_candidate = jingle_rtp_candidate_to_iceudp( |
| 247 jingle_session_get_js(session)); |
278 session, generation, candidate); |
| 248 iceudp_candidate = jingle_iceudp_candidate_new(candidate->component_id, |
279 jingle_iceudp_add_local_candidate( |
| 249 candidate->foundation, generation, id, candidate->ip, |
280 JINGLE_ICEUDP(transport), |
| 250 0, candidate->port, candidate->priority, "udp", |
281 iceudp_candidate); |
| 251 candidate->type == PURPLE_MEDIA_CANDIDATE_TYPE_HOST ? "host" : |
|
| 252 candidate->type == PURPLE_MEDIA_CANDIDATE_TYPE_SRFLX ? "srflx" : |
|
| 253 candidate->type == PURPLE_MEDIA_CANDIDATE_TYPE_PRFLX ? "prflx" : |
|
| 254 candidate->type == PURPLE_MEDIA_CANDIDATE_TYPE_RELAY ? "relay" : "", |
|
| 255 candidate->username, candidate->password); |
|
| 256 iceudp_candidate->reladdr = g_strdup(candidate->base_ip); |
|
| 257 iceudp_candidate->relport = candidate->base_port; |
|
| 258 jingle_iceudp_add_local_candidate(JINGLE_ICEUDP(transport), iceudp_candidate); |
|
| 259 g_free(id); |
|
| 260 } |
282 } |
| 261 return transport; |
283 return transport; |
| 262 } else { |
284 } else { |
| 263 return NULL; |
285 return NULL; |
| 264 } |
286 } |
| 329 } |
351 } |
| 330 |
352 |
| 331 static void |
353 static void |
| 332 jingle_rtp_new_candidate_cb(PurpleMedia *media, gchar *sid, gchar *name, PurpleMediaCandidate *candidate, JingleSession *session) |
354 jingle_rtp_new_candidate_cb(PurpleMedia *media, gchar *sid, gchar *name, PurpleMediaCandidate *candidate, JingleSession *session) |
| 333 { |
355 { |
| |
356 JingleContent *content = jingle_session_find_content( |
| |
357 session, sid, "initiator"); |
| |
358 JingleTransport *transport; |
| |
359 |
| 334 purple_debug_info("jingle-rtp", "jingle_rtp_new_candidate_cb\n"); |
360 purple_debug_info("jingle-rtp", "jingle_rtp_new_candidate_cb\n"); |
| |
361 |
| |
362 if (content == NULL) |
| |
363 content = jingle_session_find_content( |
| |
364 session, sid, "responder"); |
| |
365 |
| |
366 if (content == NULL) { |
| |
367 purple_debug_error("jingle-rtp", |
| |
368 "jingle_rtp_new_candidate_cb: " |
| |
369 "Can't find session %s\n", sid); |
| |
370 return; |
| |
371 } |
| |
372 |
| |
373 transport = jingle_content_get_transport(content); |
| |
374 |
| |
375 if (JINGLE_IS_ICEUDP(transport)) |
| |
376 jingle_iceudp_add_local_candidate(transport, |
| |
377 jingle_rtp_candidate_to_iceudp( |
| |
378 session, 1, candidate)); |
| |
379 else if (JINGLE_IS_RAWUDP(transport)) |
| |
380 jingle_rawudp_add_local_candidate(transport, |
| |
381 jingle_rtp_candidate_to_rawudp( |
| |
382 session, 1, candidate)); |
| |
383 |
| |
384 g_object_unref(transport); |
| |
385 |
| |
386 jabber_iq_send(jingle_session_to_packet(session, |
| |
387 JINGLE_TRANSPORT_INFO)); |
| 335 } |
388 } |
| 336 |
389 |
| 337 static void |
390 static void |
| 338 jingle_rtp_initiate_ack_cb(JabberStream *js, xmlnode *packet, gpointer data) |
391 jingle_rtp_initiate_ack_cb(JabberStream *js, xmlnode *packet, gpointer data) |
| 339 { |
392 { |
| 357 JabberIq *iq = jingle_session_to_packet( |
410 JabberIq *iq = jingle_session_to_packet( |
| 358 session, JINGLE_SESSION_INITIATE); |
411 session, JINGLE_SESSION_INITIATE); |
| 359 jabber_iq_set_callback(iq, |
412 jabber_iq_set_callback(iq, |
| 360 jingle_rtp_initiate_ack_cb, session); |
413 jingle_rtp_initiate_ack_cb, session); |
| 361 jabber_iq_send(iq); |
414 jabber_iq_send(iq); |
| |
415 g_signal_connect(G_OBJECT(media), "new-candidate", |
| |
416 G_CALLBACK(jingle_rtp_new_candidate_cb), session); |
| 362 } else { |
417 } else { |
| 363 jabber_iq_send(jingle_session_to_packet(session, JINGLE_SESSION_ACCEPT)); |
418 jabber_iq_send(jingle_session_to_packet(session, JINGLE_SESSION_ACCEPT)); |
| |
419 g_signal_connect(G_OBJECT(media), "new-candidate", |
| |
420 G_CALLBACK(jingle_rtp_new_candidate_cb), session); |
| 364 } |
421 } |
| 365 } else if (sid != NULL && name != NULL) { |
422 } else if (sid != NULL && name != NULL) { |
| 366 JingleContent *content = jingle_session_find_content(session, sid, "initiator"); |
423 JingleContent *content = jingle_session_find_content(session, sid, "initiator"); |
| 367 JingleTransport *oldtransport = jingle_content_get_transport(content); |
424 JingleTransport *oldtransport = jingle_content_get_transport(content); |
| 368 GList *candidates = purple_media_get_local_candidates(media, sid, name); |
425 GList *candidates = purple_media_get_local_candidates(media, sid, name); |
| 416 /* connect callbacks */ |
473 /* connect callbacks */ |
| 417 g_signal_connect(G_OBJECT(media), "accepted", |
474 g_signal_connect(G_OBJECT(media), "accepted", |
| 418 G_CALLBACK(jingle_rtp_accepted_cb), session); |
475 G_CALLBACK(jingle_rtp_accepted_cb), session); |
| 419 g_signal_connect(G_OBJECT(media), "codecs-changed", |
476 g_signal_connect(G_OBJECT(media), "codecs-changed", |
| 420 G_CALLBACK(jingle_rtp_codecs_changed_cb), session); |
477 G_CALLBACK(jingle_rtp_codecs_changed_cb), session); |
| 421 g_signal_connect(G_OBJECT(media), "new-candidate", |
|
| 422 G_CALLBACK(jingle_rtp_new_candidate_cb), session); |
|
| 423 g_signal_connect(G_OBJECT(media), "ready-new", |
478 g_signal_connect(G_OBJECT(media), "ready-new", |
| 424 G_CALLBACK(jingle_rtp_ready_cb), session); |
479 G_CALLBACK(jingle_rtp_ready_cb), session); |
| 425 g_signal_connect(G_OBJECT(media), "state-changed", |
480 g_signal_connect(G_OBJECT(media), "state-changed", |
| 426 G_CALLBACK(jingle_rtp_state_changed_cb), session); |
481 G_CALLBACK(jingle_rtp_state_changed_cb), session); |
| 427 |
482 |