summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMikhail Zabaluev <mikhail.zabaluev@nokia.com>2010-03-11 19:49:00 +0200
committerMikhail Zabaluev <mikhail.zabaluev@nokia.com>2010-03-12 15:57:08 +0200
commitae08dacb9426ac3d64c4d507888fbad4b8eee429 (patch)
tree3bd15bdf6a7060494cc13a63b820f6472b62b95a /src
parent222df2c563a641c2dfd73c2e94b51cde8d69becc (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.c4
-rw-r--r--src/sip-media-channel.c107
-rw-r--r--src/sip-media-channel.h4
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,