diff options
author | Mikhail Zabaluev <mikhail.zabaluev@nokia.com> | 2010-03-11 19:49:00 +0200 |
---|---|---|
committer | Mikhail Zabaluev <mikhail.zabaluev@nokia.com> | 2010-03-12 15:57:08 +0200 |
commit | ae08dacb9426ac3d64c4d507888fbad4b8eee429 (patch) | |
tree | 3bd15bdf6a7060494cc13a63b820f6472b62b95a /src | |
parent | 222df2c563a641c2dfd73c2e94b51cde8d69becc (diff) |
Create and emit the session after emitting NewChannel(s)
Only the old-skool RequestChannel will add members and create streams before
the channel is emitted.
Diffstat (limited to 'src')
-rw-r--r-- | src/media-factory.c | 4 | ||||
-rw-r--r-- | src/sip-media-channel.c | 107 | ||||
-rw-r--r-- | src/sip-media-channel.h | 4 |
3 files changed, 61 insertions, 54 deletions
diff --git a/src/media-factory.c b/src/media-factory.c index 24974b2..2beff4d 100644 --- a/src/media-factory.c +++ b/src/media-factory.c @@ -357,8 +357,6 @@ tpsip_nua_i_invite_cb (TpBaseConnection *conn, channel = new_media_channel (fac, handle, handle, channel_flags); - tpsip_media_channel_receive_invite (channel, ev->nua_handle); - tp_handle_unref (contact_repo, handle); /* We delay emission of NewChannel(s) until we have the data on @@ -366,6 +364,8 @@ tpsip_nua_i_invite_cb (TpBaseConnection *conn, g_signal_connect (channel, "incoming-call", G_CALLBACK (incoming_call_cb), fac); + tpsip_media_channel_attach_to_nua_handle (channel, ev->nua_handle); + return TRUE; } diff --git a/src/sip-media-channel.c b/src/sip-media-channel.c index 6414e24..9a21b8a 100644 --- a/src/sip-media-channel.c +++ b/src/sip-media-channel.c @@ -1049,13 +1049,15 @@ tpsip_media_channel_create_initial_streams (TpsipMediaChannel *self) TRUE); } -/** - * Handle an incoming INVITE, normally called just after the channel - * has been created with initiator handle of the sender. +/* + * Handles an incoming call, called shortly after the channel + * has been created with initiator handle of the sender, when remote SDP + * session data are reported by the NUA stack. */ -void -tpsip_media_channel_receive_invite (TpsipMediaChannel *self, - nua_handle_t *nh) +static void +tpsip_media_channel_handle_incoming_call (TpsipMediaChannel *self, + nua_handle_t *nh, + const sdp_session_t *sdp) { TpsipMediaChannelPrivate *priv = TPSIP_MEDIA_CHANNEL_GET_PRIVATE (self); TpBaseConnection *conn = TP_BASE_CONNECTION (priv->conn); @@ -1063,8 +1065,36 @@ tpsip_media_channel_receive_invite (TpsipMediaChannel *self, g_assert (priv->initiator != conn->self_handle); g_assert (priv->session == NULL); - /* Start the local stream-engine; once the local - * media are ready, reply with nua_respond() */ + if (sdp != NULL) + { + /* Get the initial media properties from the session offer */ + const sdp_media_t *media; + + for (media = sdp->sdp_media; media != NULL; media = media->m_next) + { + if (media->m_rejected || media->m_port == 0) + continue; + + switch (media->m_type) + { + case sdp_media_audio: + priv->initial_audio = TRUE; + DEBUG("has initial audio"); + break; + case sdp_media_video: + priv->initial_video = TRUE; + DEBUG("has initial video"); + break; + default: + break; + } + } + } + + /* Tell the factory to emit NewChannel(s) */ + g_signal_emit (self, signals[SIG_INCOMING_CALL], 0); + + /* Offer the session handler to the client */ priv_create_session (self, nh, priv->initiator); g_assert (priv->session != NULL); @@ -1285,34 +1315,6 @@ priv_nua_i_cancel_cb (TpsipMediaChannel *self, return TRUE; } -static void -priv_initial_media_properties_from_sdp (TpsipMediaChannel *self, - const sdp_session_t *sdp) -{ - TpsipMediaChannelPrivate *priv = TPSIP_MEDIA_CHANNEL_GET_PRIVATE (self); - const sdp_media_t *media; - - for (media = sdp->sdp_media; media != NULL; media = media->m_next) - { - if (media->m_rejected || media->m_port == 0) - continue; - - switch (media->m_type) - { - case sdp_media_audio: - priv->initial_audio = TRUE; - DEBUG("has initial audio"); - break; - case sdp_media_video: - priv->initial_video = TRUE; - DEBUG("has initial video"); - break; - default: - break; - } - } -} - static gboolean priv_nua_i_state_cb (TpsipMediaChannel *self, const TpsipNuaEvent *ev, @@ -1327,8 +1329,6 @@ priv_nua_i_state_cb (TpsipMediaChannel *self, gint status = ev->status; TpHandle peer; - g_return_val_if_fail (priv->session != NULL, FALSE); - tl_gets(tags, NUTAG_CALLSTATE_REF(ss_state), NUTAG_OFFER_RECV_REF(offer_recv), @@ -1336,6 +1336,18 @@ priv_nua_i_state_cb (TpsipMediaChannel *self, SOATAG_REMOTE_SDP_REF(r_sdp), TAG_END()); + DEBUG("call with handle %p is %s", ev->nua_handle, nua_callstate_name (ss_state)); + + if (ss_state == nua_callstate_received) + { + /* We get the session data for initial media properties with this event; + * initialize the session before we can create any streams below. + */ + tpsip_media_channel_handle_incoming_call (self, ev->nua_handle, r_sdp); + } + + g_return_val_if_fail (priv->session != NULL, FALSE); + if (r_sdp) { g_return_val_if_fail (answer_recv || offer_recv, FALSE); @@ -1348,15 +1360,8 @@ priv_nua_i_state_cb (TpsipMediaChannel *self, peer = tpsip_media_session_get_peer (priv->session); - DEBUG("call with handle %p is %s", ev->nua_handle, nua_callstate_name (ss_state)); - switch ((enum nua_callstate)ss_state) { - case nua_callstate_received: - if (r_sdp != NULL) - priv_initial_media_properties_from_sdp (self, r_sdp); - g_signal_emit (self, signals[SIG_INCOMING_CALL], 0); - break; case nua_callstate_proceeding: switch (status) { @@ -1548,8 +1553,9 @@ static void priv_session_state_changed_cb (TpsipMediaSession *session, tp_intset_destroy (set); } -static void -priv_connect_nua_handlers (TpsipMediaChannel *self, nua_handle_t *nh) +void +tpsip_media_channel_attach_to_nua_handle (TpsipMediaChannel *self, + nua_handle_t *nh) { TpsipMediaChannelPrivate *priv = TPSIP_MEDIA_CHANNEL_GET_PRIVATE (self); @@ -1604,9 +1610,6 @@ priv_create_session (TpsipMediaChannel *channel, g_assert (priv->session == NULL); - /* Bind the channel object to the handle to handle NUA events */ - priv_connect_nua_handlers (channel, nh); - object_path = g_strdup_printf ("%s/MediaSession%u", priv->object_path, peer); DEBUG("allocating session, peer=%u", peer); @@ -1686,6 +1689,10 @@ priv_outbound_call (TpsipMediaChannel *channel, nh = tpsip_conn_create_request_handle (priv->conn, peer); priv_create_session (channel, nh, peer); + + /* Bind the channel object to the handle to handle NUA events */ + tpsip_media_channel_attach_to_nua_handle (channel, nh); + nua_handle_unref (nh); } else diff --git a/src/sip-media-channel.h b/src/sip-media-channel.h index be6dd7a..9cb28b7 100644 --- a/src/sip-media-channel.h +++ b/src/sip-media-channel.h @@ -78,8 +78,8 @@ gboolean _tpsip_media_channel_add_member (GObject *iface, void tpsip_media_channel_create_initial_streams (TpsipMediaChannel *self); -void tpsip_media_channel_receive_invite (TpsipMediaChannel *self, - nua_handle_t *nh); +void tpsip_media_channel_attach_to_nua_handle (TpsipMediaChannel *self, + nua_handle_t *nh); guint tpsip_media_channel_change_call_state (TpsipMediaChannel *self, |