mirror of
https://gitlab.gnome.org/GNOME/calls.git
synced 2025-01-07 12:25:31 +00:00
sip: initial call handling
* implement answering and hangup * (de)activate media pipeline
This commit is contained in:
parent
967f30d688
commit
e0482fc6e6
4 changed files with 106 additions and 27 deletions
|
@ -22,6 +22,8 @@
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#define G_LOG_DOMAIN "CallsSipCall"
|
||||||
|
|
||||||
#include "calls-sip-call.h"
|
#include "calls-sip-call.h"
|
||||||
|
|
||||||
#include "calls-message-source.h"
|
#include "calls-message-source.h"
|
||||||
|
@ -94,18 +96,34 @@ static void
|
||||||
answer (CallsCall *call)
|
answer (CallsCall *call)
|
||||||
{
|
{
|
||||||
CallsSipCall *self;
|
CallsSipCall *self;
|
||||||
|
g_autofree gchar *local_sdp = NULL;
|
||||||
|
|
||||||
g_assert (CALLS_IS_CALL (call));
|
g_assert (CALLS_IS_CALL (call));
|
||||||
g_assert (CALLS_IS_SIP_CALL (call));
|
g_assert (CALLS_IS_SIP_CALL (call));
|
||||||
|
|
||||||
self = CALLS_SIP_CALL (call);
|
self = CALLS_SIP_CALL (call);
|
||||||
|
|
||||||
|
g_assert (self->nh);
|
||||||
|
|
||||||
if (self->state != CALLS_CALL_STATE_INCOMING) {
|
if (self->state != CALLS_CALL_STATE_INCOMING) {
|
||||||
g_warning ("Call must be in 'incoming' state in order to answer");
|
g_warning ("Call must be in 'incoming' state in order to answer");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* need to include SDP answer here */
|
/* XXX dynamically get free ports */
|
||||||
|
calls_sip_call_setup_local_media (self, 19042, 19043);
|
||||||
|
|
||||||
|
local_sdp = calls_sip_media_manager_static_capabilities (self->manager,
|
||||||
|
19042,
|
||||||
|
FALSE);
|
||||||
|
|
||||||
|
g_assert (local_sdp);
|
||||||
|
g_debug ("Setting local SDP to string:\n%s", local_sdp);
|
||||||
|
|
||||||
|
nua_respond (self->nh, 200, NULL,
|
||||||
|
SOATAG_USER_SDP_STR (local_sdp),
|
||||||
|
SOATAG_AF (SOA_AF_IP4_IP6),
|
||||||
|
TAG_END ());
|
||||||
|
|
||||||
change_state (self, CALLS_CALL_STATE_ACTIVE);
|
change_state (self, CALLS_CALL_STATE_ACTIVE);
|
||||||
}
|
}
|
||||||
|
@ -120,6 +138,31 @@ hang_up (CallsCall *call)
|
||||||
|
|
||||||
self = CALLS_SIP_CALL (call);
|
self = CALLS_SIP_CALL (call);
|
||||||
|
|
||||||
|
switch (self->state) {
|
||||||
|
case CALLS_CALL_STATE_DIALING:
|
||||||
|
nua_cancel (self->nh, TAG_END ());
|
||||||
|
g_debug ("Hanging up on outgoing ringing call");
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CALLS_CALL_STATE_ACTIVE:
|
||||||
|
nua_bye (self->nh, TAG_END ());
|
||||||
|
|
||||||
|
g_debug ("Hanging up ongoing call");
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CALLS_CALL_STATE_INCOMING:
|
||||||
|
nua_respond (self->nh, 480, NULL, TAG_END ());
|
||||||
|
g_debug ("Hanging up incoming call");
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CALLS_CALL_STATE_DISCONNECTED:
|
||||||
|
g_warning ("Tried hanging up already disconnected call");
|
||||||
|
return;
|
||||||
|
|
||||||
|
default:
|
||||||
|
g_warning ("Hanging up not possible in state %d", self->state);
|
||||||
|
}
|
||||||
|
|
||||||
change_state (self, CALLS_CALL_STATE_DISCONNECTED);
|
change_state (self, CALLS_CALL_STATE_DISCONNECTED);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -301,14 +344,15 @@ calls_sip_call_setup_remote_media (CallsSipCall *self,
|
||||||
|
|
||||||
void
|
void
|
||||||
calls_sip_call_activate_media (CallsSipCall *self,
|
calls_sip_call_activate_media (CallsSipCall *self,
|
||||||
gboolean enabled)
|
gboolean enabled)
|
||||||
{
|
{
|
||||||
g_return_if_fail (CALLS_IS_SIP_CALL (self));
|
g_return_if_fail (CALLS_IS_SIP_CALL (self));
|
||||||
|
g_return_if_fail (CALLS_IS_SIP_MEDIA_PIPELINE (self->pipeline));
|
||||||
|
|
||||||
if (enabled) {
|
if (enabled) {
|
||||||
;
|
calls_sip_media_pipeline_start (self->pipeline);
|
||||||
} else {
|
} else {
|
||||||
;
|
calls_sip_media_pipeline_stop (self->pipeline);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -336,3 +380,15 @@ calls_sip_call_new (const gchar *number,
|
||||||
|
|
||||||
return call;
|
return call;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
calls_sip_call_set_state (CallsSipCall *self,
|
||||||
|
CallsCallState state)
|
||||||
|
{
|
||||||
|
g_return_if_fail (CALLS_IS_SIP_CALL (self));
|
||||||
|
|
||||||
|
g_print ("Changed call state to %d\n", state);
|
||||||
|
self->state = state;
|
||||||
|
g_object_notify_by_pspec (G_OBJECT (self), props[PROP_CALL_STATE]);
|
||||||
|
}
|
||||||
|
|
|
@ -24,6 +24,8 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "calls-call.h"
|
||||||
|
|
||||||
#include <glib-object.h>
|
#include <glib-object.h>
|
||||||
#include <sofia-sip/nua.h>
|
#include <sofia-sip/nua.h>
|
||||||
|
|
||||||
|
@ -45,5 +47,7 @@ void calls_sip_call_setup_local_media (CallsSipCall *self
|
||||||
guint port_rtcp);
|
guint port_rtcp);
|
||||||
void calls_sip_call_activate_media (CallsSipCall *self,
|
void calls_sip_call_activate_media (CallsSipCall *self,
|
||||||
gboolean enabled);
|
gboolean enabled);
|
||||||
|
void calls_sip_call_set_state (CallsSipCall *self,
|
||||||
|
CallsCallState state);
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
|
|
|
@ -269,8 +269,8 @@ sip_i_state (int status,
|
||||||
default:
|
default:
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
g_object_set (call, "state", state, NULL);
|
|
||||||
|
|
||||||
|
calls_sip_call_set_state (call, state);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -288,20 +288,22 @@ sip_callback (nua_event_t event,
|
||||||
CallsSipOrigin *origin = CALLS_SIP_ORIGIN (magic);
|
CallsSipOrigin *origin = CALLS_SIP_ORIGIN (magic);
|
||||||
/* op currently unused */
|
/* op currently unused */
|
||||||
CallsSipHandles *op = hmagic;
|
CallsSipHandles *op = hmagic;
|
||||||
|
const char * from = NULL;
|
||||||
|
|
||||||
switch (event) {
|
switch (event) {
|
||||||
case nua_i_invite:
|
case nua_i_invite:
|
||||||
/* This needs to be handled by CallsSipCall */
|
tl_gets (tags, SIPTAG_FROM_STR_REF (from), TAG_END ());
|
||||||
//g_debug ("incoming call INVITE: %03d %s", status, phrase);
|
|
||||||
//origin->oper->incoming_call_handle = nh;
|
|
||||||
///* We can only handle a single call */
|
|
||||||
//if (origin->call_state != SIP_CALL_READY) {
|
|
||||||
// const char * from = NULL;
|
|
||||||
|
|
||||||
// tl_gets (tags, SIPTAG_FROM_STR_REF (from), TAG_END ());
|
g_debug ("incoming call INVITE: %03d %s from %s", status, phrase, from);
|
||||||
|
|
||||||
|
/* reject if there already is a ongoing call */
|
||||||
|
if (op->call_handle) {
|
||||||
|
nua_respond (nh, 486, NULL, TAG_END ());
|
||||||
|
g_debug ("Cannot handle more than one call. Rejecting");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
calls_sip_origin_create_inbound (origin, from, nh);
|
||||||
|
|
||||||
// g_debug ("Rejecting call from %s", from);
|
|
||||||
// nua_respond (nh, 486, NULL, TAG_END ());
|
|
||||||
//}
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case nua_r_invite:
|
case nua_r_invite:
|
||||||
|
@ -440,7 +442,6 @@ setup_sip_handles (CallsSipOrigin *self)
|
||||||
NUTAG_REGISTRAR (self->host),
|
NUTAG_REGISTRAR (self->host),
|
||||||
TAG_END ());
|
TAG_END ());
|
||||||
oper->call_handle = NULL;
|
oper->call_handle = NULL;
|
||||||
oper->incoming_call_handle = NULL;
|
|
||||||
|
|
||||||
return oper;
|
return oper;
|
||||||
}
|
}
|
||||||
|
@ -564,6 +565,10 @@ remove_call (CallsSipOrigin *self,
|
||||||
"nua-handle", &nh,
|
"nua-handle", &nh,
|
||||||
NULL);
|
NULL);
|
||||||
|
|
||||||
|
/* TODO support multiple simultaneous calls */
|
||||||
|
if (self->oper->call_handle == nh)
|
||||||
|
self->oper->call_handle = NULL;
|
||||||
|
|
||||||
g_hash_table_remove (self->call_handles, nh);
|
g_hash_table_remove (self->call_handles, nh);
|
||||||
nua_handle_unref (nh);
|
nua_handle_unref (nh);
|
||||||
|
|
||||||
|
@ -596,7 +601,6 @@ remove_calls (CallsSipOrigin *self,
|
||||||
g_hash_table_remove_all (self->call_handles);
|
g_hash_table_remove_all (self->call_handles);
|
||||||
|
|
||||||
g_clear_pointer (&self->oper->call_handle, nua_handle_unref);
|
g_clear_pointer (&self->oper->call_handle, nua_handle_unref);
|
||||||
g_clear_pointer (&self->oper->incoming_call_handle, nua_handle_unref);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -646,15 +650,26 @@ add_call (CallsSipOrigin *self,
|
||||||
SOATAG_AF (SOA_AF_IP4_IP6),
|
SOATAG_AF (SOA_AF_IP4_IP6),
|
||||||
TAG_END ());
|
TAG_END ());
|
||||||
|
|
||||||
|
if (self->oper->call_handle)
|
||||||
|
nua_handle_unref (self->oper->call_handle);
|
||||||
|
|
||||||
self->oper->call_handle = handle;
|
self->oper->call_handle = handle;
|
||||||
|
|
||||||
|
g_hash_table_insert (self->call_handles, handle, sip_call);
|
||||||
|
|
||||||
|
if (!inbound)
|
||||||
|
nua_invite (self->oper->call_handle,
|
||||||
|
SIPTAG_TO_STR (address),
|
||||||
|
SOATAG_RTP_SORT (SOA_RTP_SORT_REMOTE),
|
||||||
|
SOATAG_RTP_SELECT (SOA_RTP_SELECT_ALL),
|
||||||
|
TAG_END ());
|
||||||
|
|
||||||
call = CALLS_CALL (sip_call);
|
call = CALLS_CALL (sip_call);
|
||||||
g_signal_connect_swapped (call, "state-changed",
|
g_signal_connect_swapped (call, "state-changed",
|
||||||
G_CALLBACK (on_call_state_changed_cb),
|
G_CALLBACK (on_call_state_changed_cb),
|
||||||
self);
|
self);
|
||||||
|
|
||||||
self->calls = g_list_append (self->calls, sip_call);
|
self->calls = g_list_append (self->calls, sip_call);
|
||||||
g_hash_table_insert (self->call_handles, handle, sip_call);
|
|
||||||
|
|
||||||
g_signal_emit_by_name (CALLS_ORIGIN (self), "call-added", call);
|
g_signal_emit_by_name (CALLS_ORIGIN (self), "call-added", call);
|
||||||
}
|
}
|
||||||
|
@ -665,6 +680,7 @@ dial (CallsOrigin *origin,
|
||||||
const gchar *address)
|
const gchar *address)
|
||||||
{
|
{
|
||||||
CallsSipOrigin *self;
|
CallsSipOrigin *self;
|
||||||
|
nua_handle_t *nh;
|
||||||
g_assert (CALLS_ORIGIN (origin));
|
g_assert (CALLS_ORIGIN (origin));
|
||||||
g_assert (CALLS_IS_SIP_ORIGIN (origin));
|
g_assert (CALLS_IS_SIP_ORIGIN (origin));
|
||||||
|
|
||||||
|
@ -676,15 +692,14 @@ dial (CallsOrigin *origin,
|
||||||
|
|
||||||
self = CALLS_SIP_ORIGIN (origin);
|
self = CALLS_SIP_ORIGIN (origin);
|
||||||
|
|
||||||
if (self->oper->call_handle)
|
nh = nua_handle (self->nua, self->oper,
|
||||||
nua_handle_unref (self->oper->call_handle);
|
NUTAG_MEDIA_ENABLE (1),
|
||||||
|
SOATAG_ACTIVE_AUDIO (SOA_ACTIVE_SENDRECV),
|
||||||
|
TAG_END ());
|
||||||
|
|
||||||
self->oper->call_handle = nua_handle (self->nua, self->oper,
|
g_debug ("Calling `%s'", address);
|
||||||
NUTAG_MEDIA_ENABLE (1),
|
|
||||||
SOATAG_ACTIVE_AUDIO (SOA_ACTIVE_SENDRECV),
|
|
||||||
TAG_END ());
|
|
||||||
|
|
||||||
add_call (CALLS_SIP_ORIGIN (origin), address, FALSE, self->oper->call_handle);
|
add_call (CALLS_SIP_ORIGIN (origin), address, FALSE, nh);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -821,7 +836,6 @@ calls_sip_origin_dispose (GObject *object)
|
||||||
|
|
||||||
if (self->oper) {
|
if (self->oper) {
|
||||||
g_clear_pointer (&self->oper->call_handle, nua_handle_unref);
|
g_clear_pointer (&self->oper->call_handle, nua_handle_unref);
|
||||||
g_clear_pointer (&self->oper->incoming_call_handle, nua_handle_unref);
|
|
||||||
g_clear_pointer (&self->oper->register_handle, nua_handle_unref);
|
g_clear_pointer (&self->oper->register_handle, nua_handle_unref);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -978,6 +992,12 @@ calls_sip_origin_create_inbound (CallsSipOrigin *self,
|
||||||
g_return_if_fail (address != NULL);
|
g_return_if_fail (address != NULL);
|
||||||
g_return_if_fail (CALLS_IS_SIP_ORIGIN (self));
|
g_return_if_fail (CALLS_IS_SIP_ORIGIN (self));
|
||||||
|
|
||||||
|
/* TODO support multiple calls */
|
||||||
|
if (self->oper->call_handle)
|
||||||
|
nua_handle_unref (self->oper->call_handle);
|
||||||
|
|
||||||
|
self->oper->call_handle = handle;
|
||||||
|
|
||||||
add_call (self, address, TRUE, handle);
|
add_call (self, address, TRUE, handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -38,7 +38,6 @@ typedef struct
|
||||||
{
|
{
|
||||||
nua_handle_t *register_handle;
|
nua_handle_t *register_handle;
|
||||||
nua_handle_t *call_handle;
|
nua_handle_t *call_handle;
|
||||||
nua_handle_t *incoming_call_handle;
|
|
||||||
CallsSipContext *context;
|
CallsSipContext *context;
|
||||||
} CallsSipHandles;
|
} CallsSipHandles;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue