Statistics
| Branch: | Revision:

janus-gateway / plugins / janus_sip.c @ d66e7f1b

History | View | Annotate | Download (122 KB)

1
/*! \file   janus_sip.c
2
 * \author Lorenzo Miniero <lorenzo@meetecho.com>
3
 * \copyright GNU General Public License v3
4
 * \brief  Janus SIP plugin
5
 * \details  This is a simple SIP plugin for Janus, allowing WebRTC peers
6
 * to register at a SIP server (e.g., Asterisk) and call SIP user agents
7
 * through the gateway. Specifically, when attaching to the plugin peers
8
 * are requested to provide their SIP server credentials, i.e., the address
9
 * of the SIP server and their username/secret. This results in the plugin
10
 * registering at the SIP server and acting as a SIP client on behalf of
11
 * the web peer. Most of the SIP states and lifetime are masked by the plugin,
12
 * and only the relevant events (e.g., INVITEs and BYEs) and functionality
13
 * (call, hangup) are made available to the web peer: peers can call
14
 * extensions at the SIP server or wait for incoming INVITEs, and during
15
 * a call they can send DTMF tones. Calls can do plain RTP or SDES-SRTP.
16
 *
17
 * The concept behind this plugin is to allow different web pages associated
18
 * to the same peer, and hence the same SIP user, to attach to the plugin
19
 * at the same time and yet just do a SIP REGISTER once. The same should
20
 * apply for calls: while an incoming call would be notified to all the
21
 * web UIs associated to the peer, only one would be able to pick up and
22
 * answer, in pretty much the same way as SIP forking works but without the
23
 * need to fork in the same place. This specific functionality, though, has
24
 * not been implemented as of yet.
25
 *
26
 * \todo Only Asterisk and Kamailio have been tested as a SIP server, and
27
 * specifically only with basic audio calls: this plugin needs some work
28
 * to make it more stable and reliable.
29
 *
30
 * \section sipapi SIP Plugin API
31
 *
32
 * All requests you can send in the SIP Plugin API are asynchronous,
33
 * which means all responses (successes and errors) will be delivered
34
 * as events with the same transaction.
35
 *
36
 * The supported requests are \c register , \c call , \c accept and
37
 * \c hangup . \c register can be used, as the name suggests, to register
38
 * a username at a SIP registrar to call and be called; \c call is used
39
 * to send an INVITE to a different SIP URI through the plugin, while
40
 * \c accept is used to accept the call in case one is invited instead
41
 * of inviting; finally, \c hangup can be used to terminate the
42
 * communication at any time, either to hangup (BYE) an ongoing call or
43
 * to cancel/decline (CANCEL/BYE) a call that hasn't started yet.
44
 *
45
 * Actual API docs: TBD.
46
 *
47
 * \ingroup plugins
48
 * \ref plugins
49
 */
50

    
51
#include "plugin.h"
52

    
53
#include <arpa/inet.h>
54
#include <net/if.h>
55

    
56
#include <jansson.h>
57

    
58
#include <sofia-sip/msg_header.h>
59
#include <sofia-sip/nua.h>
60
#include <sofia-sip/sdp.h>
61
#include <sofia-sip/sip_status.h>
62
#include <sofia-sip/url.h>
63
#include <sofia-sip/tport_tag.h>
64

    
65
#include <srtp/srtp.h>
66
#include <srtp/crypto_kernel.h>
67

    
68
#include "../debug.h"
69
#include "../apierror.h"
70
#include "../config.h"
71
#include "../mutex.h"
72
#include "../record.h"
73
#include "../rtp.h"
74
#include "../rtcp.h"
75
#include "../utils.h"
76

    
77

    
78
/* Plugin information */
79
#define JANUS_SIP_VERSION                        5
80
#define JANUS_SIP_VERSION_STRING        "0.0.5"
81
#define JANUS_SIP_DESCRIPTION                "This is a simple SIP plugin for Janus, allowing WebRTC peers to register at a SIP server and call SIP user agents through the gateway."
82
#define JANUS_SIP_NAME                                "JANUS SIP plugin"
83
#define JANUS_SIP_AUTHOR                        "Meetecho s.r.l."
84
#define JANUS_SIP_PACKAGE                        "janus.plugin.sip"
85

    
86
/* Plugin methods */
87
janus_plugin *create(void);
88
int janus_sip_init(janus_callbacks *callback, const char *config_path);
89
void janus_sip_destroy(void);
90
int janus_sip_get_api_compatibility(void);
91
int janus_sip_get_version(void);
92
const char *janus_sip_get_version_string(void);
93
const char *janus_sip_get_description(void);
94
const char *janus_sip_get_name(void);
95
const char *janus_sip_get_author(void);
96
const char *janus_sip_get_package(void);
97
void janus_sip_create_session(janus_plugin_session *handle, int *error);
98
struct janus_plugin_result *janus_sip_handle_message(janus_plugin_session *handle, char *transaction, char *message, char *sdp_type, char *sdp);
99
void janus_sip_setup_media(janus_plugin_session *handle);
100
void janus_sip_incoming_rtp(janus_plugin_session *handle, int video, char *buf, int len);
101
void janus_sip_incoming_rtcp(janus_plugin_session *handle, int video, char *buf, int len);
102
void janus_sip_hangup_media(janus_plugin_session *handle);
103
void janus_sip_destroy_session(janus_plugin_session *handle, int *error);
104
char *janus_sip_query_session(janus_plugin_session *handle);
105

    
106
/* Plugin setup */
107
static janus_plugin janus_sip_plugin =
108
        JANUS_PLUGIN_INIT (
109
                .init = janus_sip_init,
110
                .destroy = janus_sip_destroy,
111

    
112
                .get_api_compatibility = janus_sip_get_api_compatibility,
113
                .get_version = janus_sip_get_version,
114
                .get_version_string = janus_sip_get_version_string,
115
                .get_description = janus_sip_get_description,
116
                .get_name = janus_sip_get_name,
117
                .get_author = janus_sip_get_author,
118
                .get_package = janus_sip_get_package,
119

    
120
                .create_session = janus_sip_create_session,
121
                .handle_message = janus_sip_handle_message,
122
                .setup_media = janus_sip_setup_media,
123
                .incoming_rtp = janus_sip_incoming_rtp,
124
                .incoming_rtcp = janus_sip_incoming_rtcp,
125
                .hangup_media = janus_sip_hangup_media,
126
                .destroy_session = janus_sip_destroy_session,
127
                .query_session = janus_sip_query_session,
128
        );
129

    
130
/* Plugin creator */
131
janus_plugin *create(void) {
132
        JANUS_LOG(LOG_VERB, "%s created!\n", JANUS_SIP_NAME);
133
        return &janus_sip_plugin;
134
}
135

    
136

    
137
/* Useful stuff */
138
static volatile gint initialized = 0, stopping = 0;
139
static janus_callbacks *gateway = NULL;
140

    
141
static char local_ip[INET6_ADDRSTRLEN];
142
static int keepalive_interval = 120;
143
static gboolean behind_nat = FALSE;
144
static char *user_agent;
145
#define JANUS_DEFAULT_REGISTER_TTL        3600
146
static int register_ttl = JANUS_DEFAULT_REGISTER_TTL;
147

    
148
static GThread *handler_thread;
149
static GThread *watchdog;
150
static void *janus_sip_handler(void *data);
151

    
152
typedef struct janus_sip_message {
153
        janus_plugin_session *handle;
154
        char *transaction;
155
        char *message;
156
        char *sdp_type;
157
        char *sdp;
158
} janus_sip_message;
159
static GAsyncQueue *messages = NULL;
160
static janus_sip_message exit_message;
161

    
162
static void janus_sip_message_free(janus_sip_message *msg) {
163
        if(!msg || msg == &exit_message)
164
                return;
165

    
166
        msg->handle = NULL;
167

    
168
        g_free(msg->transaction);
169
        msg->transaction = NULL;
170
        g_free(msg->message);
171
        msg->message = NULL;
172
        g_free(msg->sdp_type);
173
        msg->sdp_type = NULL;
174
        g_free(msg->sdp);
175
        msg->sdp = NULL;
176

    
177
        g_free(msg);
178
}
179

    
180

    
181
typedef enum {
182
        janus_sip_registration_status_disabled = -2,
183
        janus_sip_registration_status_failed = -1,
184
        janus_sip_registration_status_unregistered = 0,
185
        janus_sip_registration_status_registering,
186
        janus_sip_registration_status_registered,
187
        janus_sip_registration_status_unregistering,
188
} janus_sip_registration_status;
189

    
190
static const char *janus_sip_registration_status_string(janus_sip_registration_status status) {
191
        switch(status) {
192
                case janus_sip_registration_status_disabled:
193
                        return "disabled";
194
                case janus_sip_registration_status_failed:
195
                        return "failed";
196
                case janus_sip_registration_status_unregistered:
197
                        return "unregistered";
198
                case janus_sip_registration_status_registering:
199
                        return "registering";
200
                case janus_sip_registration_status_registered:
201
                        return "registered";
202
                case janus_sip_registration_status_unregistering:
203
                        return "unregistering";
204
                default:
205
                        return "unknown";
206
        }
207
}
208

    
209

    
210
typedef enum {
211
        janus_sip_call_status_idle = 0,
212
        janus_sip_call_status_inviting,
213
        janus_sip_call_status_invited,
214
        janus_sip_call_status_incall,
215
        janus_sip_call_status_closing,
216
} janus_sip_call_status;
217

    
218
static const char *janus_sip_call_status_string(janus_sip_call_status status) {
219
        switch(status) {
220
                case janus_sip_call_status_idle:
221
                        return "idle";
222
                case janus_sip_call_status_inviting:
223
                        return "inviting";
224
                case janus_sip_call_status_invited:
225
                        return "invited";
226
                case janus_sip_call_status_incall:
227
                        return "incall";
228
                case janus_sip_call_status_closing:
229
                        return "closing";
230
                default:
231
                        return "unknown";
232
        }
233
}
234

    
235

    
236
/* Sofia stuff */
237
typedef struct ssip_s ssip_t;
238
typedef struct ssip_oper_s ssip_oper_t;
239

    
240
typedef enum {
241
        janus_sip_secret_type_plaintext = 1,
242
        janus_sip_secret_type_hashed = 2,
243
        janus_sip_secret_type_unknown
244
} janus_sip_secret_type;
245

    
246
typedef struct janus_sip_account {
247
        char *identity;
248
        gboolean sips;
249
        char *username;
250
        char *authuser;                        /**< username to use for authentication */
251
        char *secret;
252
        janus_sip_secret_type secret_type;
253
        int sip_port;
254
        char *proxy;
255
        janus_sip_registration_status registration_status;
256
} janus_sip_account;
257

    
258
typedef struct janus_sip_media {
259
        char *remote_ip;
260
        int ready:1;
261
        gboolean require_srtp, has_srtp_local, has_srtp_remote;
262
        int has_audio:1;
263
        int audio_rtp_fd, audio_rtcp_fd;
264
        int local_audio_rtp_port, remote_audio_rtp_port;
265
        int local_audio_rtcp_port, remote_audio_rtcp_port;
266
        guint32 audio_ssrc, audio_ssrc_peer;
267
        srtp_t audio_srtp_in, audio_srtp_out;
268
        srtp_policy_t audio_remote_policy, audio_local_policy;
269
        int audio_srtp_suite_in, audio_srtp_suite_out;
270
        int has_video:1;
271
        int video_rtp_fd, video_rtcp_fd;
272
        int local_video_rtp_port, remote_video_rtp_port;
273
        int local_video_rtcp_port, remote_video_rtcp_port;
274
        guint32 video_ssrc, video_ssrc_peer;
275
        srtp_t video_srtp_in, video_srtp_out;
276
        srtp_policy_t video_remote_policy, video_local_policy;
277
        int video_srtp_suite_in, video_srtp_suite_out;
278
} janus_sip_media;
279

    
280
typedef struct janus_sip_session {
281
        janus_plugin_session *handle;
282
        ssip_t *stack;
283
        janus_sip_account account;
284
        janus_sip_call_status status;
285
        janus_sip_media media;
286
        char *transaction;
287
        char *callee;
288
        janus_recorder *arc;                /* The Janus recorder instance for this user's audio, if enabled */
289
        janus_recorder *arc_peer;        /* The Janus recorder instance for the peer's audio, if enabled */
290
        janus_recorder *vrc;                /* The Janus recorder instance for this user's video, if enabled */
291
        janus_recorder *vrc_peer;        /* The Janus recorder instance for the peer's video, if enabled */
292
        volatile gint hangingup;
293
        gint64 destroyed;        /* Time at which this session was marked as destroyed */
294
        janus_mutex mutex;
295
} janus_sip_session;
296
static GHashTable *sessions;
297
static GList *old_sessions;
298
static janus_mutex sessions_mutex;
299

    
300

    
301
#undef SU_ROOT_MAGIC_T
302
#define SU_ROOT_MAGIC_T        ssip_t
303
#undef NUA_MAGIC_T
304
#define NUA_MAGIC_T                ssip_t
305
#undef NUA_HMAGIC_T
306
#define NUA_HMAGIC_T        ssip_oper_t
307

    
308
struct ssip_s {
309
        su_home_t s_home[1];
310
        su_root_t *s_root;
311
        nua_t *s_nua;
312
        nua_handle_t *s_nh_r, *s_nh_i;
313
        janus_sip_session *session;
314
};
315

    
316

    
317
/* SRTP stuff (in case we need SDES) */
318
#define SRTP_MASTER_KEY_LENGTH        16
319
#define SRTP_MASTER_SALT_LENGTH        14
320
#define SRTP_MASTER_LENGTH (SRTP_MASTER_KEY_LENGTH + SRTP_MASTER_SALT_LENGTH)
321
static const char *janus_sip_srtp_error[] =
322
{
323
        "err_status_ok",
324
        "err_status_fail",
325
        "err_status_bad_param",
326
        "err_status_alloc_fail",
327
        "err_status_dealloc_fail",
328
        "err_status_init_fail",
329
        "err_status_terminus",
330
        "err_status_auth_fail",
331
        "err_status_cipher_fail",
332
        "err_status_replay_fail",
333
        "err_status_replay_old",
334
        "err_status_algo_fail",
335
        "err_status_no_such_op",
336
        "err_status_no_ctx",
337
        "err_status_cant_check",
338
        "err_status_key_expired",
339
        "err_status_socket_err",
340
        "err_status_signal_err",
341
        "err_status_nonce_bad",
342
        "err_status_read_fail",
343
        "err_status_write_fail",
344
        "err_status_parse_err",
345
        "err_status_encode_err",
346
        "err_status_semaphore_err",
347
        "err_status_pfkey_err",
348
};
349
static const gchar *janus_sip_get_srtp_error(int error) {
350
        if(error < 0 || error > 24)
351
                return NULL;
352
        return janus_sip_srtp_error[error];
353
}
354
static int janus_sip_srtp_set_local(janus_sip_session *session, gboolean video, char **crypto) {
355
        if(session == NULL)
356
                return -1;
357
        /* Generate key/salt */
358
        uint8_t *key = g_malloc0(SRTP_MASTER_LENGTH);
359
        crypto_get_random(key, SRTP_MASTER_LENGTH);
360
        /* Set SRTP policies */
361
        srtp_policy_t *policy = video ? &session->media.video_local_policy : &session->media.audio_local_policy;
362
        crypto_policy_set_rtp_default(&(policy->rtp));
363
        crypto_policy_set_rtcp_default(&(policy->rtcp));
364
        policy->ssrc.type = ssrc_any_inbound;
365
        policy->key = key;
366
        policy->next = NULL;
367
        /* Create SRTP context */
368
        err_status_t res = srtp_create(video ? &session->media.video_srtp_out : &session->media.audio_srtp_out, policy);
369
        if(res != err_status_ok) {
370
                /* Something went wrong... */
371
                JANUS_LOG(LOG_ERR, "Oops, error creating outbound SRTP session: %d (%s)\n", res, janus_sip_get_srtp_error(res));
372
                g_free(key);
373
                policy->key = NULL;
374
                return -2;
375
        }
376
        /* Base64 encode the salt */
377
        *crypto = g_base64_encode(key, SRTP_MASTER_LENGTH);
378
        if((video && session->media.video_srtp_out) || (!video && session->media.audio_srtp_out)) {
379
                JANUS_LOG(LOG_VERB, "%s outbound SRTP session created\n", video ? "Video" : "Audio");
380
        }
381
        return 0;
382
}
383
static int janus_sip_srtp_set_remote(janus_sip_session *session, gboolean video, const char *crypto, int suite) {
384
        if(session == NULL || crypto == NULL)
385
                return -1;
386
        /* Base64 decode the crypto string and set it as the remote SRTP context */
387
        gsize len = 0;
388
        guchar *decoded = g_base64_decode(crypto, &len);
389
        if(len < SRTP_MASTER_LENGTH) {
390
                /* FIXME Can this happen? */
391
                g_free(decoded);
392
                return -2;
393
        }
394
        /* Set SRTP policies */
395
        srtp_policy_t *policy = video ? &session->media.video_remote_policy : &session->media.audio_remote_policy;
396
        crypto_policy_set_rtp_default(&(policy->rtp));
397
        crypto_policy_set_rtcp_default(&(policy->rtcp));
398
        if(suite == 32) {
399
                crypto_policy_set_aes_cm_128_hmac_sha1_32(&(policy->rtp));
400
                crypto_policy_set_aes_cm_128_hmac_sha1_32(&(policy->rtcp));
401
        } else if(suite == 80) {
402
                crypto_policy_set_aes_cm_128_hmac_sha1_80(&(policy->rtp));
403
                crypto_policy_set_aes_cm_128_hmac_sha1_80(&(policy->rtcp));
404
        }
405
        policy->ssrc.type = ssrc_any_inbound;
406
        policy->key = decoded;
407
        policy->next = NULL;
408
        /* Create SRTP context */
409
        err_status_t res = srtp_create(video ? &session->media.video_srtp_in : &session->media.audio_srtp_in, policy);
410
        if(res != err_status_ok) {
411
                /* Something went wrong... */
412
                JANUS_LOG(LOG_ERR, "Oops, error creating inbound SRTP session: %d (%s)\n", res, janus_sip_get_srtp_error(res));
413
                g_free(decoded);
414
                policy->key = NULL;
415
                return -2;
416
        }
417
        if((video && session->media.video_srtp_in) || (!video && session->media.audio_srtp_in)) {
418
                JANUS_LOG(LOG_VERB, "%s inbound SRTP session created\n", video ? "Video" : "Audio");
419
        }
420
        return 0;
421
}
422
static void janus_sip_srtp_cleanup(janus_sip_session *session) {
423
        if(session == NULL)
424
                return;
425
        session->media.require_srtp = FALSE;
426
        session->media.has_srtp_local = FALSE;
427
        session->media.has_srtp_remote = FALSE;
428
        /* Audio */
429
        if(session->media.audio_srtp_out)
430
                srtp_dealloc(session->media.audio_srtp_out);
431
        session->media.audio_srtp_out = NULL;
432
        g_free(session->media.audio_local_policy.key);
433
        session->media.audio_local_policy.key = NULL;
434
        session->media.audio_srtp_suite_out = 0;
435
        if(session->media.audio_srtp_in)
436
                srtp_dealloc(session->media.audio_srtp_in);
437
        session->media.audio_srtp_in = NULL;
438
        g_free(session->media.audio_remote_policy.key);
439
        session->media.audio_remote_policy.key = NULL;
440
        session->media.audio_srtp_suite_in = 0;
441
        /* Video */
442
        if(session->media.video_srtp_out)
443
                srtp_dealloc(session->media.video_srtp_out);
444
        session->media.video_srtp_out = NULL;
445
        g_free(session->media.video_local_policy.key);
446
        session->media.video_local_policy.key = NULL;
447
        session->media.video_srtp_suite_out = 0;
448
        if(session->media.video_srtp_in)
449
                srtp_dealloc(session->media.video_srtp_in);
450
        session->media.video_srtp_in = NULL;
451
        g_free(session->media.video_remote_policy.key);
452
        session->media.video_remote_policy.key = NULL;
453
        session->media.video_srtp_suite_in = 0;
454
}
455

    
456

    
457
/* Sofia Event thread */
458
gpointer janus_sip_sofia_thread(gpointer user_data);
459
/* Sofia callbacks */
460
void janus_sip_sofia_callback(nua_event_t event, int status, char const *phrase, nua_t *nua, nua_magic_t *magic, nua_handle_t *nh, nua_hmagic_t *hmagic, sip_t const *sip, tagi_t tags[]);
461
/* SDP parsing and manipulation */
462
void janus_sip_sdp_process(janus_sip_session *session, sdp_session_t *sdp);
463
char *janus_sip_sdp_manipulate(janus_sip_session *session, sdp_session_t *sdp);
464
/* Media */
465
static int janus_sip_allocate_local_ports(janus_sip_session *session);
466
static void *janus_sip_relay_thread(void *data);
467

    
468

    
469
/* URI parsing utilies */
470

    
471
#define JANUS_SIP_URI_MAXLEN        1024
472
typedef struct {
473
        char data[JANUS_SIP_URI_MAXLEN];
474
        url_t url[1];
475
} janus_sip_uri_t;
476

    
477
/* Parses a SIP URI (SIPS is not supported), returns 0 on success, -1 otherwise */
478
static int janus_sip_parse_uri(janus_sip_uri_t *sip_uri, const char *data) {
479
        g_strlcpy(sip_uri->data, data, JANUS_SIP_URI_MAXLEN);
480
        if (url_d(sip_uri->url, sip_uri->data) < 0 || sip_uri->url->url_type != url_sip)
481
                return -1;
482
        return 0;
483
}
484

    
485
/* Similar to th above function, but it also accepts SIPS URIs */
486
static int janus_sip_parse_proxy_uri(janus_sip_uri_t *sip_uri, const char *data) {
487
        g_strlcpy(sip_uri->data, data, JANUS_SIP_URI_MAXLEN);
488
        if (url_d(sip_uri->url, sip_uri->data) < 0 || (sip_uri->url->url_type != url_sip && sip_uri->url->url_type != url_sips))
489
                return -1;
490
        return 0;
491
}
492

    
493
/* Error codes */
494
#define JANUS_SIP_ERROR_UNKNOWN_ERROR                499
495
#define JANUS_SIP_ERROR_NO_MESSAGE                        440
496
#define JANUS_SIP_ERROR_INVALID_JSON                441
497
#define JANUS_SIP_ERROR_INVALID_REQUEST                442
498
#define JANUS_SIP_ERROR_MISSING_ELEMENT                443
499
#define JANUS_SIP_ERROR_INVALID_ELEMENT                444
500
#define JANUS_SIP_ERROR_ALREADY_REGISTERED        445
501
#define JANUS_SIP_ERROR_INVALID_ADDRESS                446
502
#define JANUS_SIP_ERROR_WRONG_STATE                        447
503
#define JANUS_SIP_ERROR_MISSING_SDP                        448
504
#define JANUS_SIP_ERROR_LIBSOFIA_ERROR                449
505
#define JANUS_SIP_ERROR_IO_ERROR                        450
506
#define JANUS_SIP_ERROR_RECORDING_ERROR                451
507
#define JANUS_SIP_ERROR_TOO_STRICT                        452
508

    
509

    
510
/* SIP watchdog/garbage collector (sort of) */
511
void *janus_sip_watchdog(void *data);
512
void *janus_sip_watchdog(void *data) {
513
        JANUS_LOG(LOG_INFO, "SIP watchdog started\n");
514
        gint64 now = 0;
515
        while(g_atomic_int_get(&initialized) && !g_atomic_int_get(&stopping)) {
516
                janus_mutex_lock(&sessions_mutex);
517
                /* Iterate on all the sessions */
518
                now = janus_get_monotonic_time();
519
                if(old_sessions != NULL) {
520
                        GList *sl = old_sessions;
521
                        JANUS_LOG(LOG_HUGE, "Checking %d old SIP sessions...\n", g_list_length(old_sessions));
522
                        while(sl) {
523
                                janus_sip_session *session = (janus_sip_session *)sl->data;
524
                                if(!session) {
525
                                        sl = sl->next;
526
                                        continue;
527
                                }
528
                                if (now-session->destroyed >= 5*G_USEC_PER_SEC) {
529
                                        /* We're lazy and actually get rid of the stuff only after a few seconds */
530
                                        JANUS_LOG(LOG_VERB, "Freeing old SIP session\n");
531
                                        GList *rm = sl->next;
532
                                        old_sessions = g_list_delete_link(old_sessions, sl);
533
                                        sl = rm;
534
                                        if (session->account.identity) {
535
                                            g_free(session->account.identity);
536
                                            session->account.identity = NULL;
537
                                        }
538
                                        session->account.sips = TRUE;
539
                                        if (session->account.proxy) {
540
                                            g_free(session->account.proxy);
541
                                            session->account.proxy = NULL;
542
                                        }
543
                                        if (session->account.secret) {
544
                                            g_free(session->account.secret);
545
                                            session->account.secret = NULL;
546
                                        }
547
                                        if (session->account.username) {
548
                                            g_free(session->account.username);
549
                                            session->account.username = NULL;
550
                                        }
551
                                        if (session->account.authuser) {
552
                                            g_free(session->account.authuser);
553
                                            session->account.authuser = NULL;
554
                                        }
555
                                        if (session->callee) {
556
                                            g_free(session->callee);
557
                                            session->callee = NULL;
558
                                        }
559
                                        if (session->transaction) {
560
                                            g_free(session->transaction);
561
                                            session->transaction = NULL;
562
                                        }
563
                                        if (session->media.remote_ip) {
564
                                            g_free(session->media.remote_ip);
565
                                            session->media.remote_ip = NULL;
566
                                        }
567
                                        janus_sip_srtp_cleanup(session);
568
                                        session->handle = NULL;
569
                                        g_free(session);
570
                                        session = NULL;
571
                                        continue;
572
                                }
573
                                sl = sl->next;
574
                        }
575
                }
576
                janus_mutex_unlock(&sessions_mutex);
577
                g_usleep(500000);
578
        }
579
        JANUS_LOG(LOG_INFO, "SIP watchdog stopped\n");
580
        return NULL;
581
}
582

    
583

    
584
static void janus_sip_detect_local_ip(char *buf, size_t buflen) {
585
        JANUS_LOG(LOG_VERB, "Autodetecting local IP...\n");
586

    
587
        struct sockaddr_in addr;
588
        socklen_t len;
589
        int fd = socket(AF_INET, SOCK_DGRAM, 0);
590
        if (fd == -1)
591
                goto error;
592
        addr.sin_family = AF_INET;
593
        addr.sin_port = htons(1);
594
        inet_pton(AF_INET, "1.2.3.4", &addr.sin_addr.s_addr);
595
        if (connect(fd, (const struct sockaddr*) &addr, sizeof(addr)) < 0)
596
                goto error;
597
        len = sizeof(addr);
598
        if (getsockname(fd, (struct sockaddr*) &addr, &len) < 0)
599
                goto error;
600
        if (getnameinfo((const struct sockaddr*) &addr, sizeof(addr),
601
                        buf, buflen,
602
                        NULL, 0, NI_NUMERICHOST) != 0)
603
                goto error;
604
        close(fd);
605
        return;
606

    
607
error:
608
        if (fd != -1)
609
                close(fd);
610
        JANUS_LOG(LOG_VERB, "Couldn't find any address! using 127.0.0.1 as the local IP... (which is NOT going to work out of your machine)\n");
611
        g_strlcpy(buf, "127.0.0.1", buflen);
612
}
613

    
614

    
615
/* Plugin implementation */
616
int janus_sip_init(janus_callbacks *callback, const char *config_path) {
617
        if(g_atomic_int_get(&stopping)) {
618
                /* Still stopping from before */
619
                return -1;
620
        }
621
        if(callback == NULL || config_path == NULL) {
622
                /* Invalid arguments */
623
                return -1;
624
        }
625

    
626
        /* Read configuration */
627
        char filename[255];
628
        g_snprintf(filename, 255, "%s/%s.cfg", config_path, JANUS_SIP_PACKAGE);
629
        JANUS_LOG(LOG_VERB, "Configuration file: %s\n", filename);
630
        janus_config *config = janus_config_parse(filename);
631
        if(config != NULL)
632
                janus_config_print(config);
633

    
634
        gboolean local_ip_set = FALSE;
635
        janus_config_item *item = janus_config_get_item_drilldown(config, "general", "local_ip");
636
        if(item && item->value) {
637
                int family;
638
                if (!janus_is_ip_valid(item->value, &family)) {
639
                        JANUS_LOG(LOG_WARN, "Invalid local IP specified: %s, guessing the default...\n", item->value);
640
                } else {
641
                        /* Verify that we can actually bind to that address */
642
                        int fd = socket(family, SOCK_DGRAM, 0);
643
                        if (fd == -1) {
644
                                JANUS_LOG(LOG_WARN, "Error creating test socket, falling back to detecting IP address...\n");
645
                        } else {
646
                                int r;
647
                                struct sockaddr_storage ss;
648
                                socklen_t addrlen;
649
                                memset(&ss, 0, sizeof(ss));
650
                                if (family == AF_INET) {
651
                                        struct sockaddr_in *addr4 = (struct sockaddr_in*)&ss;
652
                                        addr4->sin_family = AF_INET;
653
                                        addr4->sin_port = 0;
654
                                        inet_pton(AF_INET, item->value, &(addr4->sin_addr.s_addr));
655
                                        addrlen = sizeof(struct sockaddr_in);
656
                                } else {
657
                                        struct sockaddr_in6 *addr6 = (struct sockaddr_in6*)&ss;
658
                                        addr6->sin6_family = AF_INET6;
659
                                        addr6->sin6_port = 0;
660
                                        inet_pton(AF_INET6, item->value, &(addr6->sin6_addr.s6_addr));
661
                                        addrlen = sizeof(struct sockaddr_in6);
662
                                }
663
                                r = bind(fd, (const struct sockaddr*)&ss, addrlen);
664
                                close(fd);
665
                                if (r < 0) {
666
                                        JANUS_LOG(LOG_WARN, "Error setting local IP address to %s, falling back to detecting IP address...\n", item->value);
667
                                } else {
668
                                        g_strlcpy(local_ip, item->value, sizeof(local_ip));
669
                                        local_ip_set = TRUE;
670
                                }
671
                        }
672
                }
673
        }
674
        if (!local_ip_set)
675
                janus_sip_detect_local_ip(local_ip, sizeof(local_ip));
676
        JANUS_LOG(LOG_VERB, "Local IP set to %s\n", local_ip);
677

    
678
        item = janus_config_get_item_drilldown(config, "general", "keepalive_interval");
679
        if(item && item->value)
680
                keepalive_interval = atoi(item->value);
681
        JANUS_LOG(LOG_VERB, "SIP keep-alive interval set to %d seconds\n", keepalive_interval);
682

    
683
        item = janus_config_get_item_drilldown(config, "general", "register_ttl");
684
        if(item && item->value)
685
                register_ttl = atoi(item->value);
686
        JANUS_LOG(LOG_VERB, "SIP registration TTL set to %d seconds\n", register_ttl);
687

    
688
        item = janus_config_get_item_drilldown(config, "general", "behind_nat");
689
        if(item && item->value)
690
                behind_nat = janus_is_true(item->value);
691

    
692
        item = janus_config_get_item_drilldown(config, "general", "user_agent");
693
        if(item && item->value)
694
                user_agent = g_strdup(item->value);
695
        else
696
                user_agent = g_strdup("Janus WebRTC Gateway SIP Plugin "JANUS_SIP_VERSION_STRING);
697
        JANUS_LOG(LOG_VERB, "SIP User-Agent set to %s\n", user_agent);
698

    
699
        /* This plugin actually has nothing to configure... */
700
        janus_config_destroy(config);
701
        config = NULL;
702

    
703
        /* Setup sofia */
704
        su_init();
705

    
706
        sessions = g_hash_table_new(NULL, NULL);
707
        janus_mutex_init(&sessions_mutex);
708
        messages = g_async_queue_new_full((GDestroyNotify) janus_sip_message_free);
709
        /* This is the callback we'll need to invoke to contact the gateway */
710
        gateway = callback;
711

    
712
        g_atomic_int_set(&initialized, 1);
713

    
714
        GError *error = NULL;
715
        /* Start the sessions watchdog */
716
        watchdog = g_thread_try_new("etest watchdog", &janus_sip_watchdog, NULL, &error);
717
        if(error != NULL) {
718
                g_atomic_int_set(&initialized, 0);
719
                JANUS_LOG(LOG_ERR, "Got error %d (%s) trying to launch the SIP watchdog thread...\n", error->code, error->message ? error->message : "??");
720
                return -1;
721
        }
722
        /* Launch the thread that will handle incoming messages */
723
        handler_thread = g_thread_try_new("janus sip handler", janus_sip_handler, NULL, &error);
724
        if(error != NULL) {
725
                g_atomic_int_set(&initialized, 0);
726
                JANUS_LOG(LOG_ERR, "Got error %d (%s) trying to launch the SIP handler thread...\n", error->code, error->message ? error->message : "??");
727
                return -1;
728
        }
729
        JANUS_LOG(LOG_INFO, "%s initialized!\n", JANUS_SIP_NAME);
730
        return 0;
731
}
732

    
733
void janus_sip_destroy(void) {
734
        if(!g_atomic_int_get(&initialized))
735
                return;
736
        g_atomic_int_set(&stopping, 1);
737

    
738
        g_async_queue_push(messages, &exit_message);
739
        if(handler_thread != NULL) {
740
                g_thread_join(handler_thread);
741
                handler_thread = NULL;
742
        }
743
        if(watchdog != NULL) {
744
                g_thread_join(watchdog);
745
                watchdog = NULL;
746
        }
747
        /* FIXME We should destroy the sessions cleanly */
748
        janus_mutex_lock(&sessions_mutex);
749
        g_hash_table_destroy(sessions);
750
        janus_mutex_unlock(&sessions_mutex);
751
        g_async_queue_unref(messages);
752
        messages = NULL;
753
        sessions = NULL;
754
        g_atomic_int_set(&initialized, 0);
755
        g_atomic_int_set(&stopping, 0);
756
        JANUS_LOG(LOG_INFO, "%s destroyed!\n", JANUS_SIP_NAME);
757
}
758

    
759
int janus_sip_get_api_compatibility(void) {
760
        /* Important! This is what your plugin MUST always return: don't lie here or bad things will happen */
761
        return JANUS_PLUGIN_API_VERSION;
762
}
763

    
764
int janus_sip_get_version(void) {
765
        return JANUS_SIP_VERSION;
766
}
767

    
768
const char *janus_sip_get_version_string(void) {
769
        return JANUS_SIP_VERSION_STRING;
770
}
771

    
772
const char *janus_sip_get_description(void) {
773
        return JANUS_SIP_DESCRIPTION;
774
}
775

    
776
const char *janus_sip_get_name(void) {
777
        return JANUS_SIP_NAME;
778
}
779

    
780
const char *janus_sip_get_author(void) {
781
        return JANUS_SIP_AUTHOR;
782
}
783

    
784
const char *janus_sip_get_package(void) {
785
        return JANUS_SIP_PACKAGE;
786
}
787

    
788
void janus_sip_create_session(janus_plugin_session *handle, int *error) {
789
        if(g_atomic_int_get(&stopping) || !g_atomic_int_get(&initialized)) {
790
                *error = -1;
791
                return;
792
        }
793
        janus_sip_session *session = g_malloc0(sizeof(janus_sip_session));
794
        session->handle = handle;
795
        session->account.identity = NULL;
796
        session->account.sips = TRUE;
797
        session->account.username = NULL;
798
        session->account.authuser = NULL;
799
        session->account.secret = NULL;
800
        session->account.secret_type = janus_sip_secret_type_unknown;
801
        session->account.sip_port = 0;
802
        session->account.proxy = NULL;
803
        session->account.registration_status = janus_sip_registration_status_unregistered;
804
        session->status = janus_sip_call_status_idle;
805
        session->stack = NULL;
806
        session->transaction = NULL;
807
        session->callee = NULL;
808
        session->media.remote_ip = NULL;
809
        session->media.ready = 0;
810
        session->media.require_srtp = FALSE;
811
        session->media.has_srtp_local = FALSE;
812
        session->media.has_srtp_remote = FALSE;
813
        session->media.has_audio = 0;
814
        session->media.audio_rtp_fd = -1;
815
        session->media.audio_rtcp_fd= -1;
816
        session->media.local_audio_rtp_port = 0;
817
        session->media.remote_audio_rtp_port = 0;
818
        session->media.local_audio_rtcp_port = 0;
819
        session->media.remote_audio_rtcp_port = 0;
820
        session->media.audio_ssrc = 0;
821
        session->media.audio_ssrc_peer = 0;
822
        session->media.audio_srtp_suite_in = 0;
823
        session->media.audio_srtp_suite_out = 0;
824
        session->media.has_video = 0;
825
        session->media.video_rtp_fd = -1;
826
        session->media.video_rtcp_fd= -1;
827
        session->media.local_video_rtp_port = 0;
828
        session->media.remote_video_rtp_port = 0;
829
        session->media.local_video_rtcp_port = 0;
830
        session->media.remote_video_rtcp_port = 0;
831
        session->media.video_ssrc = 0;
832
        session->media.video_ssrc_peer = 0;
833
        session->media.video_srtp_suite_in = 0;
834
        session->media.video_srtp_suite_out = 0;
835
        session->destroyed = 0;
836
        g_atomic_int_set(&session->hangingup, 0);
837
        janus_mutex_init(&session->mutex);
838
        handle->plugin_handle = session;
839

    
840
        janus_mutex_lock(&sessions_mutex);
841
        g_hash_table_insert(sessions, handle, session);
842
        janus_mutex_unlock(&sessions_mutex);
843

    
844
        return;
845
}
846

    
847
void janus_sip_destroy_session(janus_plugin_session *handle, int *error) {
848
        if(g_atomic_int_get(&stopping) || !g_atomic_int_get(&initialized)) {
849
                *error = -1;
850
                return;
851
        }
852
        janus_sip_session *session = (janus_sip_session *)handle->plugin_handle;
853
        if(!session) {
854
                JANUS_LOG(LOG_ERR, "No SIP session associated with this handle...\n");
855
                *error = -2;
856
                return;
857
        }
858
        janus_mutex_lock(&sessions_mutex);
859
        if(!session->destroyed) {
860
                g_hash_table_remove(sessions, handle);
861
                janus_sip_hangup_media(handle);
862
                session->destroyed = janus_get_monotonic_time();
863
                JANUS_LOG(LOG_VERB, "Destroying SIP session (%s)...\n", session->account.username ? session->account.username : "unregistered user");
864
                if(session->stack != NULL) {
865
                        /* Shutdown the NUA: this will remove the session later on */
866
                        nua_shutdown(session->stack->s_nua);
867
                } else {
868
                        /* No stack, maybe never registered: cleaning up and removing the session is done in a lazy way */
869
                        old_sessions = g_list_append(old_sessions, session);
870
                }
871
        }
872
        janus_mutex_unlock(&sessions_mutex);
873
        return;
874
}
875

    
876
char *janus_sip_query_session(janus_plugin_session *handle) {
877
        if(g_atomic_int_get(&stopping) || !g_atomic_int_get(&initialized)) {
878
                return NULL;
879
        }
880
        janus_sip_session *session = (janus_sip_session *)handle->plugin_handle;
881
        if(!session) {
882
                JANUS_LOG(LOG_ERR, "No session associated with this handle...\n");
883
                return NULL;
884
        }
885
        /* Provide some generic info, e.g., if we're in a call and with whom */
886
        json_t *info = json_object();
887
        json_object_set_new(info, "username", session->account.username ? json_string(session->account.username) : NULL);
888
        json_object_set_new(info, "identity", session->account.identity ? json_string(session->account.identity) : NULL);
889
        json_object_set_new(info, "registration_status", json_string(janus_sip_registration_status_string(session->account.registration_status)));
890
        json_object_set_new(info, "call_status", json_string(janus_sip_call_status_string(session->status)));
891
        if(session->callee) {
892
                json_object_set_new(info, "callee", json_string(session->callee ? session->callee : "??"));
893
                json_object_set_new(info, "srtp-required", json_string(session->media.require_srtp ? "yes" : "no"));
894
                json_object_set_new(info, "sdes-local", json_string(session->media.has_srtp_local ? "yes" : "no"));
895
                json_object_set_new(info, "sdes-remote", json_string(session->media.has_srtp_remote ? "yes" : "no"));
896
        }
897
        if(session->arc || session->vrc || session->arc_peer || session->vrc_peer) {
898
                json_t *recording = json_object();
899
                if(session->arc && session->arc->filename)
900
                        json_object_set_new(recording, "audio", json_string(session->arc->filename));
901
                if(session->vrc && session->vrc->filename)
902
                        json_object_set_new(recording, "video", json_string(session->vrc->filename));
903
                if(session->arc_peer && session->arc_peer->filename)
904
                        json_object_set_new(recording, "audio-peer", json_string(session->arc_peer->filename));
905
                if(session->vrc_peer && session->vrc_peer->filename)
906
                        json_object_set_new(recording, "video-peer", json_string(session->vrc_peer->filename));
907
                json_object_set_new(info, "recording", recording);
908
        }
909
        json_object_set_new(info, "destroyed", json_integer(session->destroyed));
910
        char *info_text = json_dumps(info, JSON_INDENT(3) | JSON_PRESERVE_ORDER);
911
        json_decref(info);
912
        return info_text;
913
}
914

    
915
struct janus_plugin_result *janus_sip_handle_message(janus_plugin_session *handle, char *transaction, char *message, char *sdp_type, char *sdp) {
916
        if(g_atomic_int_get(&stopping) || !g_atomic_int_get(&initialized))
917
                return janus_plugin_result_new(JANUS_PLUGIN_ERROR, g_atomic_int_get(&stopping) ? "Shutting down" : "Plugin not initialized");
918
        JANUS_LOG(LOG_VERB, "%s\n", message);
919
        janus_sip_message *msg = g_malloc0(sizeof(janus_sip_message));
920
        msg->handle = handle;
921
        msg->transaction = transaction;
922
        msg->message = message;
923
        msg->sdp_type = sdp_type;
924
        msg->sdp = sdp;
925
        g_async_queue_push(messages, msg);
926

    
927
        /* All the requests to this plugin are handled asynchronously */
928
        return janus_plugin_result_new(JANUS_PLUGIN_OK_WAIT, NULL);
929
}
930

    
931
void janus_sip_setup_media(janus_plugin_session *handle) {
932
        JANUS_LOG(LOG_INFO, "WebRTC media is now available\n");
933
        if(g_atomic_int_get(&stopping) || !g_atomic_int_get(&initialized))
934
                return;
935
        janus_sip_session *session = (janus_sip_session *)handle->plugin_handle;
936
        if(!session) {
937
                JANUS_LOG(LOG_ERR, "No session associated with this handle...\n");
938
                return;
939
        }
940
        if(session->destroyed)
941
                return;
942
        g_atomic_int_set(&session->hangingup, 0);
943
        /* TODO Only relay RTP/RTCP when we get this event */
944
}
945

    
946
void janus_sip_incoming_rtp(janus_plugin_session *handle, int video, char *buf, int len) {
947
        if(handle == NULL || handle->stopped || g_atomic_int_get(&stopping) || !g_atomic_int_get(&initialized))
948
                return;
949
        if(gateway) {
950
                /* Honour the audio/video active flags */
951
                janus_sip_session *session = (janus_sip_session *)handle->plugin_handle;
952
                if(!session || session->destroyed) {
953
                        JANUS_LOG(LOG_ERR, "No session associated with this handle...\n");
954
                        return;
955
                }
956
                if(session->status != janus_sip_call_status_incall)
957
                        return;
958
                /* Forward to our SIP peer */
959
                if(video) {
960
                        if(session->media.video_ssrc == 0) {
961
                                rtp_header *header = (rtp_header *)buf;
962
                                session->media.video_ssrc = ntohl(header->ssrc);
963
                                JANUS_LOG(LOG_VERB, "Got SIP video SSRC: %"SCNu32"\n", session->media.video_ssrc);
964
                        }
965
                        if(session->media.has_video && session->media.video_rtp_fd) {
966
                                /* Save the frame if we're recording */
967
                                if(session->vrc)
968
                                        janus_recorder_save_frame(session->vrc, buf, len);
969
                                /* Is SRTP involved? */
970
                                if(session->media.has_srtp_local) {
971
                                        char sbuf[2048];
972
                                        memcpy(&sbuf, buf, len);
973
                                        int protected = len;
974
                                        int res = srtp_protect(session->media.video_srtp_out, &sbuf, &protected);
975
                                        if(res != err_status_ok) {
976
                                                rtp_header *header = (rtp_header *)&sbuf;
977
                                                guint32 timestamp = ntohl(header->timestamp);
978
                                                guint16 seq = ntohs(header->seq_number);
979
                                                JANUS_LOG(LOG_ERR, "[SIP-%s] Video SRTP protect error... %s (len=%d-->%d, ts=%"SCNu32", seq=%"SCNu16")...\n",
980
                                                        session->account.username, janus_sip_get_srtp_error(res), len, protected, timestamp, seq);
981
                                        } else {
982
                                                /* Forward the frame to the peer */
983
                                                send(session->media.video_rtp_fd, sbuf, protected, 0);
984
                                        }
985
                                } else {
986
                                        /* Forward the frame to the peer */
987
                                        send(session->media.video_rtp_fd, buf, len, 0);
988
                                }
989
                        }
990
                } else {
991
                        if(session->media.audio_ssrc == 0) {
992
                                rtp_header *header = (rtp_header *)buf;
993
                                session->media.audio_ssrc = ntohl(header->ssrc);
994
                                JANUS_LOG(LOG_VERB, "Got SIP audio SSRC: %"SCNu32"\n", session->media.audio_ssrc);
995
                        }
996
                        if(session->media.has_audio && session->media.audio_rtp_fd) {
997
                                /* Save the frame if we're recording */
998
                                if(session->arc)
999
                                        janus_recorder_save_frame(session->arc, buf, len);
1000
                                /* Is SRTP involved? */
1001
                                if(session->media.has_srtp_local) {
1002
                                        char sbuf[2048];
1003
                                        memcpy(&sbuf, buf, len);
1004
                                        int protected = len;
1005
                                        int res = srtp_protect(session->media.audio_srtp_out, &sbuf, &protected);
1006
                                        if(res != err_status_ok) {
1007
                                                rtp_header *header = (rtp_header *)&sbuf;
1008
                                                guint32 timestamp = ntohl(header->timestamp);
1009
                                                guint16 seq = ntohs(header->seq_number);
1010
                                                JANUS_LOG(LOG_ERR, "[SIP-%s] Audio SRTP protect error... %s (len=%d-->%d, ts=%"SCNu32", seq=%"SCNu16")...\n",
1011
                                                        session->account.username, janus_sip_get_srtp_error(res), len, protected, timestamp, seq);
1012
                                        } else {
1013
                                                /* Forward the frame to the peer */
1014
                                                send(session->media.audio_rtp_fd, sbuf, protected, 0);
1015
                                        }
1016
                                } else {
1017
                                        /* Forward the frame to the peer */
1018
                                        send(session->media.audio_rtp_fd, buf, len, 0);
1019
                                }
1020
                        }
1021
                }
1022
        }
1023
}
1024

    
1025
void janus_sip_incoming_rtcp(janus_plugin_session *handle, int video, char *buf, int len) {
1026
        if(handle == NULL || handle->stopped || g_atomic_int_get(&stopping) || !g_atomic_int_get(&initialized))
1027
                return;
1028
        if(gateway) {
1029
                janus_sip_session *session = (janus_sip_session *)handle->plugin_handle;
1030
                if(!session || session->destroyed) {
1031
                        JANUS_LOG(LOG_ERR, "No session associated with this handle...\n");
1032
                        return;
1033
                }
1034
                if(session->status != janus_sip_call_status_incall)
1035
                        return;
1036
                /* Forward to our SIP peer */
1037
                if(video) {
1038
                        if(session->media.has_video && session->media.video_rtcp_fd) {
1039
                                /* Is SRTP involved? */
1040
                                if(session->media.has_srtp_local) {
1041
                                        char sbuf[2048];
1042
                                        memcpy(&sbuf, buf, len);
1043
                                        int protected = len;
1044
                                        int res = srtp_protect_rtcp(session->media.video_srtp_out, &sbuf, &protected);
1045
                                        if(res != err_status_ok) {
1046
                                                JANUS_LOG(LOG_ERR, "[SIP-%s] Video SRTCP protect error... %s (len=%d-->%d)...\n",
1047
                                                        session->account.username, janus_sip_get_srtp_error(res), len, protected);
1048
                                        } else {
1049
                                                /* Fix SSRCs as the gateway does */
1050
                                                JANUS_LOG(LOG_HUGE, "[SIP] Fixing SSRCs (local %u, peer %u)\n",
1051
                                                        session->media.video_ssrc, session->media.video_ssrc_peer);
1052
                                                janus_rtcp_fix_ssrc((char *)buf, len, 1, session->media.video_ssrc, session->media.video_ssrc_peer);
1053
                                                /* Forward the message to the peer */
1054
                                                send(session->media.video_rtcp_fd, sbuf, protected, 0);
1055
                                        }
1056
                                } else {
1057
                                        /* Fix SSRCs as the gateway does */
1058
                                        JANUS_LOG(LOG_HUGE, "[SIP] Fixing SSRCs (local %u, peer %u)\n",
1059
                                                session->media.video_ssrc, session->media.video_ssrc_peer);
1060
                                        janus_rtcp_fix_ssrc((char *)buf, len, 1, session->media.video_ssrc, session->media.video_ssrc_peer);
1061
                                        /* Forward the message to the peer */
1062
                                        send(session->media.video_rtcp_fd, buf, len, 0);
1063
                                }
1064
                        }
1065
                } else {
1066
                        if(session->media.has_audio && session->media.audio_rtcp_fd) {
1067
                                /* Is SRTP involved? */
1068
                                if(session->media.has_srtp_local) {
1069
                                        char sbuf[2048];
1070
                                        memcpy(&sbuf, buf, len);
1071
                                        int protected = len;
1072
                                        int res = srtp_protect_rtcp(session->media.audio_srtp_out, &sbuf, &protected);
1073
                                        if(res != err_status_ok) {
1074
                                                JANUS_LOG(LOG_ERR, "[SIP-%s] Audio SRTCP protect error... %s (len=%d-->%d)...\n",
1075
                                                        session->account.username, janus_sip_get_srtp_error(res), len, protected);
1076
                                        } else {
1077
                                                /* Fix SSRCs as the gateway does */
1078
                                                JANUS_LOG(LOG_HUGE, "[SIP] Fixing SSRCs (local %u, peer %u)\n",
1079
                                                        session->media.audio_ssrc, session->media.audio_ssrc_peer);
1080
                                                janus_rtcp_fix_ssrc((char *)buf, len, 1, session->media.audio_ssrc, session->media.audio_ssrc_peer);
1081
                                                /* Forward the message to the peer */
1082
                                                send(session->media.audio_rtcp_fd, sbuf, protected, 0);
1083
                                        }
1084
                                } else {
1085
                                        /* Fix SSRCs as the gateway does */
1086
                                        JANUS_LOG(LOG_HUGE, "[SIP] Fixing SSRCs (local %u, peer %u)\n",
1087
                                                session->media.audio_ssrc, session->media.audio_ssrc_peer);
1088
                                        janus_rtcp_fix_ssrc((char *)buf, len, 1, session->media.audio_ssrc, session->media.audio_ssrc_peer);
1089
                                        /* Forward the message to the peer */
1090
                                        send(session->media.audio_rtcp_fd, buf, len, 0);
1091
                                }
1092
                        }
1093
                }
1094
        }
1095
}
1096

    
1097
void janus_sip_hangup_media(janus_plugin_session *handle) {
1098
        JANUS_LOG(LOG_INFO, "No WebRTC media anymore\n");
1099
        if(g_atomic_int_get(&stopping) || !g_atomic_int_get(&initialized))
1100
                return;
1101
        janus_sip_session *session = (janus_sip_session *)handle->plugin_handle;
1102
        if(!session) {
1103
                JANUS_LOG(LOG_ERR, "No session associated with this handle...\n");
1104
                return;
1105
        }
1106
        if(session->destroyed)
1107
                return;
1108
        if(g_atomic_int_add(&session->hangingup, 1))
1109
                return;
1110
        if(!(session->status == janus_sip_call_status_inviting ||
1111
                 session->status == janus_sip_call_status_invited ||
1112
                 session->status == janus_sip_call_status_incall))
1113
                return;
1114
        /* Get rid of the recorders, if available */
1115
        if(session->arc) {
1116
                janus_recorder_close(session->arc);
1117
                JANUS_LOG(LOG_INFO, "Closed user's audio recording %s\n", session->arc->filename ? session->arc->filename : "??");
1118
                janus_recorder_free(session->arc);
1119
        }
1120
        session->arc = NULL;
1121
        if(session->arc_peer) {
1122
                janus_recorder_close(session->arc_peer);
1123
                JANUS_LOG(LOG_INFO, "Closed peer's audio recording %s\n", session->arc_peer->filename ? session->arc_peer->filename : "??");
1124
                janus_recorder_free(session->arc_peer);
1125
        }
1126
        session->arc_peer = NULL;
1127
        if(session->vrc) {
1128
                janus_recorder_close(session->vrc);
1129
                JANUS_LOG(LOG_INFO, "Closed user's video recording %s\n", session->vrc->filename ? session->vrc->filename : "??");
1130
                janus_recorder_free(session->vrc);
1131
        }
1132
        session->vrc = NULL;
1133
        if(session->vrc_peer) {
1134
                janus_recorder_close(session->vrc_peer);
1135
                JANUS_LOG(LOG_INFO, "Closed peer's video recording %s\n", session->vrc_peer->filename ? session->vrc_peer->filename : "??");
1136
                janus_recorder_free(session->vrc_peer);
1137
        }
1138
        session->vrc_peer = NULL;
1139
        /* FIXME Simulate a "hangup" coming from the browser */
1140
        janus_sip_message *msg = g_malloc0(sizeof(janus_sip_message));
1141
        msg->handle = handle;
1142
        msg->message = g_strdup("{\"request\":\"hangup\"}");
1143
        msg->transaction = NULL;
1144
        msg->sdp_type = NULL;
1145
        msg->sdp = NULL;
1146
        g_async_queue_push(messages, msg);
1147
}
1148

    
1149
/* Thread to handle incoming messages */
1150
static void *janus_sip_handler(void *data) {
1151
        JANUS_LOG(LOG_VERB, "Joining SIP handler thread\n");
1152
        janus_sip_message *msg = NULL;
1153
        int error_code = 0;
1154
        char *error_cause = g_malloc0(512);
1155
        json_t *root = NULL;
1156
        while(g_atomic_int_get(&initialized) && !g_atomic_int_get(&stopping)) {
1157
                msg = g_async_queue_pop(messages);
1158
                if(msg == NULL)
1159
                        continue;
1160
                if(msg == &exit_message)
1161
                        break;
1162
                if(msg->handle == NULL) {
1163
                        janus_sip_message_free(msg);
1164
                        continue;
1165
                }
1166
                janus_sip_session *session = NULL;
1167
                janus_mutex_lock(&sessions_mutex);
1168
                if(g_hash_table_lookup(sessions, msg->handle) != NULL ) {
1169
                        session = (janus_sip_session *)msg->handle->plugin_handle;
1170
                }
1171
                janus_mutex_unlock(&sessions_mutex);
1172
                if(!session) {
1173
                        JANUS_LOG(LOG_ERR, "No session associated with this handle...\n");
1174
                        janus_sip_message_free(msg);
1175
                        continue;
1176
                }
1177
                if(session->destroyed) {
1178
                        janus_sip_message_free(msg);
1179
                        continue;
1180
                }
1181
                /* Handle request */
1182
                error_code = 0;
1183
                root = NULL;
1184
                JANUS_LOG(LOG_VERB, "Handling message: %s\n", msg->message);
1185
                if(msg->message == NULL) {
1186
                        JANUS_LOG(LOG_ERR, "No message??\n");
1187
                        error_code = JANUS_SIP_ERROR_NO_MESSAGE;
1188
                        g_snprintf(error_cause, 512, "%s", "No message??");
1189
                        goto error;
1190
                }
1191
                json_error_t error;
1192
                root = json_loads(msg->message, 0, &error);
1193
                if(!root) {
1194
                        JANUS_LOG(LOG_ERR, "JSON error: on line %d: %s\n", error.line, error.text);
1195
                        error_code = JANUS_SIP_ERROR_INVALID_JSON;
1196
                        g_snprintf(error_cause, 512, "JSON error: on line %d: %s", error.line, error.text);
1197
                        goto error;
1198
                }
1199
                if(!json_is_object(root)) {
1200
                        JANUS_LOG(LOG_ERR, "JSON error: not an object\n");
1201
                        error_code = JANUS_SIP_ERROR_INVALID_JSON;
1202
                        g_snprintf(error_cause, 512, "JSON error: not an object");
1203
                        goto error;
1204
                }
1205
                json_t *request = json_object_get(root, "request");
1206
                if(!request) {
1207
                        JANUS_LOG(LOG_ERR, "Missing element (request)\n");
1208
                        error_code = JANUS_SIP_ERROR_MISSING_ELEMENT;
1209
                        g_snprintf(error_cause, 512, "Missing element (request)");
1210
                        goto error;
1211
                }
1212
                if(!json_is_string(request)) {
1213
                        JANUS_LOG(LOG_ERR, "Invalid element (request should be a string)\n");
1214
                        error_code = JANUS_SIP_ERROR_INVALID_ELEMENT;
1215
                        g_snprintf(error_cause, 512, "Invalid element (request should be a string)");
1216
                        goto error;
1217
                }
1218
                const char *request_text = json_string_value(request);
1219
                json_t *result = NULL;
1220
                char *sdp_type = NULL, *sdp = NULL;
1221
                if(!strcasecmp(request_text, "register")) {
1222
                        /* Send a REGISTER */
1223
                        if(session->account.registration_status > janus_sip_registration_status_unregistered) {
1224
                                JANUS_LOG(LOG_ERR, "Already registered (%s)\n", session->account.username);
1225
                                error_code = JANUS_SIP_ERROR_ALREADY_REGISTERED;
1226
                                g_snprintf(error_cause, 512, "Already registered (%s)", session->account.username);
1227
                                goto error;
1228
                        }
1229

    
1230
                        /* Cleanup old values */
1231
                        if(session->account.identity != NULL)
1232
                                g_free(session->account.identity);
1233
                        session->account.identity = NULL;
1234
                        session->account.sips = TRUE;
1235
                        if(session->account.username != NULL)
1236
                                g_free(session->account.username);
1237
                        session->account.username = NULL;
1238
                        if(session->account.authuser != NULL)
1239
                                g_free(session->account.authuser);
1240
                        session->account.authuser = NULL;
1241
                        if(session->account.secret != NULL)
1242
                                g_free(session->account.secret);
1243
                        session->account.secret = NULL;
1244
                        session->account.secret_type = janus_sip_secret_type_unknown;
1245
                        if(session->account.proxy != NULL)
1246
                                g_free(session->account.proxy);
1247
                        session->account.proxy = NULL;
1248
                        session->account.registration_status = janus_sip_registration_status_unregistered;
1249

    
1250
                        gboolean guest = FALSE;
1251
                        json_t *type = json_object_get(root, "type");
1252
                        if(type != NULL) {
1253
                                if(!json_is_string(type)) {
1254
                                        JANUS_LOG(LOG_ERR, "Invalid element (type should be a string)\n");
1255
                                        error_code = JANUS_SIP_ERROR_INVALID_ELEMENT;
1256
                                        g_snprintf(error_cause, 512, "Invalid element (type should be a string)");
1257
                                        goto error;
1258
                                }
1259
                                const char *type_text = json_string_value(type);
1260
                                if(!strcmp(type_text, "guest")) {
1261
                                        JANUS_LOG(LOG_INFO, "Registering as a guest\n");
1262
                                        guest = TRUE;
1263
                                } else {
1264
                                        JANUS_LOG(LOG_WARN, "Unknown type '%s', ignoring...\n", type_text);
1265
                                }
1266
                        }
1267

    
1268
                        gboolean send_register = TRUE;
1269
                        json_t *do_register = json_object_get(root, "send_register");
1270
                        if(do_register != NULL) {
1271
                                if(!json_is_boolean(do_register)) {
1272
                                        JANUS_LOG(LOG_ERR, "Invalid element (send_register should be boolean)\n");
1273
                                        error_code = JANUS_SIP_ERROR_INVALID_ELEMENT;
1274
                                        g_snprintf(error_cause, 512, "Invalid element (send_register should be boolean)");
1275
                                        goto error;
1276
                                }
1277
                                if(guest) {
1278
                                        JANUS_LOG(LOG_ERR, "Conflicting elements: send_register cannot be true if guest is true\n");
1279
                                        error_code = JANUS_SIP_ERROR_INVALID_ELEMENT;
1280
                                        g_snprintf(error_cause, 512, "Conflicting elements: send_register cannot be true if guest is true");
1281
                                        goto error;
1282
                                }
1283
                                send_register = json_is_true(do_register);
1284
                        }
1285

    
1286
                        gboolean sips = TRUE;
1287
                        json_t *do_sips = json_object_get(root, "sips");
1288
                        if(do_sips != NULL) {
1289
                                if(!json_is_boolean(do_sips)) {
1290
                                        JANUS_LOG(LOG_ERR, "Invalid element (sips should be boolean)\n");
1291
                                        error_code = JANUS_SIP_ERROR_INVALID_ELEMENT;
1292
                                        g_snprintf(error_cause, 512, "Invalid element (sips should be boolean)");
1293
                                        goto error;
1294
                                }
1295
                                sips = json_is_true(do_sips);
1296
                        }
1297

    
1298
                        /* Parse address */
1299
                        json_t *proxy = json_object_get(root, "proxy");
1300
                        const char *proxy_text = NULL;
1301

    
1302
                        if (proxy && !json_is_null(proxy)) {
1303
                                if(!json_is_string(proxy)) {
1304
                                        JANUS_LOG(LOG_ERR, "Invalid element (proxy should be a string)\n");
1305
                                        error_code = JANUS_SIP_ERROR_INVALID_ELEMENT;
1306
                                        g_snprintf(error_cause, 512, "Invalid element (proxy should be a string)");
1307
                                        goto error;
1308
                                }
1309
                                proxy_text = json_string_value(proxy);
1310
                                janus_sip_uri_t proxy_uri;
1311
                                if (janus_sip_parse_proxy_uri(&proxy_uri, proxy_text) < 0) {
1312
                                        JANUS_LOG(LOG_ERR, "Invalid proxy address %s\n", proxy_text);
1313
                                        error_code = JANUS_SIP_ERROR_INVALID_ADDRESS;
1314
                                        g_snprintf(error_cause, 512, "Invalid proxy address %s\n", proxy_text);
1315
                                        goto error;
1316
                                }
1317
                        }
1318

    
1319
                        /* Parse register TTL */
1320
                        int ttl = register_ttl;
1321
                        json_t *reg_ttl = json_object_get(root, "register_ttl");
1322
                        if (reg_ttl && json_is_integer(reg_ttl))
1323
                                ttl = json_integer_value(reg_ttl);
1324
                        if (ttl <= 0)
1325
                                ttl = JANUS_DEFAULT_REGISTER_TTL;
1326

    
1327
                        /* Now the user part, if needed */
1328
                        json_t *username = json_object_get(root, "username");
1329
                        if(!guest && !username) {
1330
                                /* The username is mandatory if we're not registering as guests */
1331
                                JANUS_LOG(LOG_ERR, "Missing element (username)\n");
1332
                                error_code = JANUS_SIP_ERROR_MISSING_ELEMENT;
1333
                                g_snprintf(error_cause, 512, "Missing element (username)");
1334
                                goto error;
1335
                        }
1336
                        const char *username_text = NULL;
1337
                        janus_sip_uri_t username_uri;
1338
                        char user_id[256];
1339
                        if(username) {
1340
                                if(!json_is_string(username)) {
1341
                                        JANUS_LOG(LOG_ERR, "Invalid element (username should be a string)\n");
1342
                                        error_code = JANUS_SIP_ERROR_INVALID_ELEMENT;
1343
                                        g_snprintf(error_cause, 512, "Invalid element (username should be a string)");
1344
                                        goto error;
1345
                                }
1346
                                /* Parse address */
1347
                                username_text = json_string_value(username);
1348
                                if (janus_sip_parse_uri(&username_uri, username_text) < 0) {
1349
                                        JANUS_LOG(LOG_ERR, "Invalid user address %s\n", username_text);
1350
                                        error_code = JANUS_SIP_ERROR_INVALID_ADDRESS;
1351
                                        g_snprintf(error_cause, 512, "Invalid user address %s\n", username_text);
1352
                                        goto error;
1353
                                }
1354
                                g_strlcpy(user_id, username_uri.url->url_user, sizeof(user_id));
1355
                        }
1356
                        if(guest) {
1357
                                /* Not needed, we can stop here: just pick a random username if it wasn't provided and say we're registered */
1358
                                if(!username)
1359
                                        g_snprintf(user_id, 255, "janus-sip-%"SCNu32"", g_random_int());
1360
                                JANUS_LOG(LOG_INFO, "Guest will have username %s\n", user_id);
1361
                                send_register = FALSE;
1362
                        } else {
1363
                                json_t *secret = json_object_get(root, "secret");
1364
                                json_t *ha1_secret = json_object_get(root, "ha1_secret");
1365
                                json_t *authuser = json_object_get(root, "authuser");
1366
                                if(!secret && !ha1_secret) {
1367
                                        JANUS_LOG(LOG_ERR, "Missing element (secret or ha1_secret)\n");
1368
                                        error_code = JANUS_SIP_ERROR_MISSING_ELEMENT;
1369
                                        g_snprintf(error_cause, 512, "Missing element (secret or ha1_secret)");
1370
                                        goto error;
1371
                                }
1372
                                if(secret && ha1_secret) {
1373
                                        JANUS_LOG(LOG_ERR, "Conflicting elements specified (secret and ha1_secret)\n");
1374
                                        error_code = JANUS_SIP_ERROR_INVALID_ELEMENT;
1375
                                        g_snprintf(error_cause, 512, "Conflicting elements specified (secret and ha1_secret)");
1376
                                        goto error;
1377
                                }
1378
                                const char *secret_text;
1379
                                if(secret) {
1380
                                        if(!json_is_string(secret)) {
1381
                                                JANUS_LOG(LOG_ERR, "Invalid element (secret should be a string)\n");
1382
                                                error_code = JANUS_SIP_ERROR_INVALID_ELEMENT;
1383
                                                g_snprintf(error_cause, 512, "Invalid element (secret should be a string)");
1384
                                                goto error;
1385
                                        }
1386
                                        secret_text = json_string_value(secret);
1387
                                        session->account.secret = g_strdup(secret_text);
1388
                                        session->account.secret_type = janus_sip_secret_type_plaintext;
1389
                                } else {
1390
                                        if(!json_is_string(ha1_secret)) {
1391
                                                JANUS_LOG(LOG_ERR, "Invalid element (ha1_secret should be a string)\n");
1392
                                                error_code = JANUS_SIP_ERROR_INVALID_ELEMENT;
1393
                                                g_snprintf(error_cause, 512, "Invalid element (ha1_secret should be a string)");
1394
                                                goto error;
1395
                                        }
1396
                                        secret_text = json_string_value(ha1_secret);
1397
                                        session->account.secret = g_strdup(secret_text);
1398
                                        session->account.secret_type = janus_sip_secret_type_hashed;
1399
                                }
1400
                                if (authuser) {
1401
                                        const char *authuser_text;
1402
                                        if (!json_is_string(authuser)) {
1403
                                                JANUS_LOG(LOG_ERR, "Invalid element (authentication username should be a string)\n");
1404
                                                error_code = JANUS_SIP_ERROR_INVALID_ELEMENT;
1405
                                                g_snprintf(error_cause, 512, "Invalid element (authentication username should be a string)");
1406
                                                goto error;
1407
                                        }
1408
                                        authuser_text = json_string_value(authuser);
1409
                                        session->account.authuser = g_strdup(authuser_text);
1410
                                } else {
1411
                                        session->account.authuser = g_strdup(user_id);
1412
                                }
1413
                                /* Got the values, try registering now */
1414
                                JANUS_LOG(LOG_VERB, "Registering user %s (secret %s) @ %s through %s\n",
1415
                                        username_text, secret_text, username_uri.url->url_host, proxy_text != NULL ? proxy_text : "(null)");
1416
                        }
1417

    
1418
                        session->account.identity = g_strdup(username_text);
1419
                        session->account.sips = sips;
1420
                        session->account.username = g_strdup(user_id);
1421
                        if (proxy_text) {
1422
                                session->account.proxy = g_strdup(proxy_text);
1423
                        }
1424

    
1425
                        session->account.registration_status = janus_sip_registration_status_registering;
1426
                        if(session->stack == NULL) {
1427
                                /* Start the thread first */
1428
                                GError *error = NULL;
1429
                                g_thread_try_new("worker", janus_sip_sofia_thread, session, &error);
1430
                                if(error != NULL) {
1431
                                        JANUS_LOG(LOG_ERR, "Got error %d (%s) trying to launch the SIP Sofia thread...\n", error->code, error->message ? error->message : "??");
1432
                                        error_code = JANUS_SIP_ERROR_UNKNOWN_ERROR;
1433
                                        g_snprintf(error_cause, 512, "Got error %d (%s) trying to launch the SIP Sofia thread", error->code, error->message ? error->message : "??");
1434
                                        goto error;
1435
                                }
1436
                                long int timeout = 0;
1437
                                while(session->stack == NULL || session->stack->s_nua == NULL) {
1438
                                        g_usleep(100000);
1439
                                        timeout += 100000;
1440
                                        if(timeout >= 2000000) {
1441
                                                break;
1442
                                        }
1443
                                }
1444
                                if(timeout >= 2000000) {
1445
                                        JANUS_LOG(LOG_ERR, "Two seconds passed and still no NUA, problems with the thread?\n");
1446
                                        error_code = JANUS_SIP_ERROR_UNKNOWN_ERROR;
1447
                                        g_snprintf(error_cause, 512, "Two seconds passed and still no NUA, problems with the thread?");
1448
                                        goto error;
1449
                                }
1450
                        }
1451
                        if(session->stack->s_nh_r != NULL) {
1452
                                nua_handle_destroy(session->stack->s_nh_r);
1453
                                session->stack->s_nh_r = NULL;
1454
                        }
1455

    
1456
                        if (send_register) {
1457
                                session->stack->s_nh_r = nua_handle(session->stack->s_nua, session, TAG_END());
1458
                                if(session->stack->s_nh_r == NULL) {
1459
                                        JANUS_LOG(LOG_ERR, "NUA Handle for REGISTER still null??\n");
1460
                                        error_code = JANUS_SIP_ERROR_LIBSOFIA_ERROR;
1461
                                        g_snprintf(error_cause, 512, "Invalid NUA Handle");
1462
                                        goto error;
1463
                                }
1464
                                char ttl_text[20];
1465
                                g_snprintf(ttl_text, sizeof(ttl_text), "%d", ttl);
1466
                                nua_register(session->stack->s_nh_r,
1467
                                        NUTAG_M_USERNAME(session->account.username),
1468
                                        SIPTAG_FROM_STR(username_text),
1469
                                        SIPTAG_TO_STR(username_text),
1470
                                        SIPTAG_EXPIRES_STR(ttl_text),
1471
                                        NUTAG_PROXY(proxy_text),
1472
                                        TAG_END());
1473
                                result = json_object();
1474
                                json_object_set_new(result, "event", json_string("registering"));
1475
                        } else {
1476
                                JANUS_LOG(LOG_VERB, "Not sending a SIP REGISTER: either send_register was set to false or guest mode was enabled\n");
1477
                                session->account.registration_status = janus_sip_registration_status_disabled;
1478
                                result = json_object();
1479
                                json_object_set_new(result, "event", json_string("registered"));
1480
                                json_object_set_new(result, "username", json_string(session->account.username));
1481
                                json_object_set_new(result, "register_sent", json_string("false"));
1482
                        }
1483
                } else if(!strcasecmp(request_text, "call")) {
1484
                        /* Call another peer */
1485
                        if(session->stack == NULL) {
1486
                                JANUS_LOG(LOG_ERR, "Wrong state (register first)\n");
1487
                                error_code = JANUS_SIP_ERROR_WRONG_STATE;
1488
                                g_snprintf(error_cause, 512, "Wrong state (register first)");
1489
                                goto error;
1490
                        }
1491
                        if(session->status >= janus_sip_call_status_inviting) {
1492
                                JANUS_LOG(LOG_ERR, "Wrong state (already in a call? status=%s)\n", janus_sip_call_status_string(session->status));
1493
                                error_code = JANUS_SIP_ERROR_WRONG_STATE;
1494
                                g_snprintf(error_cause, 512, "Wrong state (already in a call? status=%s)", janus_sip_call_status_string(session->status));
1495
                                goto error;
1496
                        }
1497
                        json_t *uri = json_object_get(root, "uri");
1498
                        if(!uri) {
1499
                                JANUS_LOG(LOG_ERR, "Missing element (uri)\n");
1500
                                error_code = JANUS_SIP_ERROR_MISSING_ELEMENT;
1501
                                g_snprintf(error_cause, 512, "Missing element (uri)");
1502
                                goto error;
1503
                        }
1504
                        if(!json_is_string(uri)) {
1505
                                JANUS_LOG(LOG_ERR, "Invalid element (uri should be a string)\n");
1506
                                error_code = JANUS_SIP_ERROR_INVALID_ELEMENT;
1507
                                g_snprintf(error_cause, 512, "Invalid element (uri should be a string)");
1508
                                goto error;
1509
                        }
1510
                        /* SDES-SRTP is disabled by default, let's see if we need to enable it */
1511
                        gboolean offer_srtp = FALSE, require_srtp = FALSE;
1512
                        json_t *srtp = json_object_get(root, "srtp");
1513
                        if(srtp) {
1514
                                if(!json_is_string(srtp)) {
1515
                                        JANUS_LOG(LOG_ERR, "Invalid element (srtp should be a string)\n");
1516
                                        error_code = JANUS_SIP_ERROR_INVALID_ELEMENT;
1517
                                        g_snprintf(error_cause, 512, "Invalid element (srtp should be a string)");
1518
                                        goto error;
1519
                                }
1520
                                const char *srtp_text = json_string_value(srtp);
1521
                                if(!strcasecmp(srtp_text, "sdes_optional")) {
1522
                                        /* Negotiate SDES, but make it optional */
1523
                                        offer_srtp = TRUE;
1524
                                } else if(!strcasecmp(srtp_text, "sdes_mandatory")) {
1525
                                        /* Negotiate SDES, and require it */
1526
                                        offer_srtp = TRUE;
1527
                                        require_srtp = TRUE;
1528
                                } else {
1529
                                        JANUS_LOG(LOG_ERR, "Invalid element (srtp can only be sdes_optional or sdes_mandatory)\n");
1530
                                        error_code = JANUS_SIP_ERROR_INVALID_ELEMENT;
1531
                                        g_snprintf(error_cause, 512, "Invalid element (srtp can only be sdes_optional or sdes_mandatory)");
1532
                                        goto error;
1533
                                }
1534
                        }
1535
                        /* Parse address */
1536
                        const char *uri_text = json_string_value(uri);
1537
                        janus_sip_uri_t target_uri;
1538
                        if (janus_sip_parse_uri(&target_uri, uri_text) < 0) {
1539
                                JANUS_LOG(LOG_ERR, "Invalid user address %s\n", uri_text);
1540
                                error_code = JANUS_SIP_ERROR_INVALID_ADDRESS;
1541
                                g_snprintf(error_cause, 512, "Invalid user address %s\n", uri_text);
1542
                                goto error;
1543
                        }
1544
                        /* Any SDP to handle? if not, something's wrong */
1545
                        if(!msg->sdp) {
1546
                                JANUS_LOG(LOG_ERR, "Missing SDP\n");
1547
                                error_code = JANUS_SIP_ERROR_MISSING_SDP;
1548
                                g_snprintf(error_cause, 512, "Missing SDP");
1549
                                goto error;
1550
                        }
1551
                        JANUS_LOG(LOG_VERB, "%s is calling %s\n", session->account.username, uri_text);
1552
                        JANUS_LOG(LOG_VERB, "This is involving a negotiation (%s) as well:\n%s\n", msg->sdp_type, msg->sdp);
1553
                        /* Clean up SRTP stuff from before first, in case it's still needed */
1554
                        janus_sip_srtp_cleanup(session);
1555
                        session->media.require_srtp = require_srtp;
1556
                        session->media.has_srtp_local = offer_srtp;
1557
                        if(offer_srtp) {
1558
                                JANUS_LOG(LOG_VERB, "Going to negotiate SDES-SRTP (%s)...\n", require_srtp ? "mandatory" : "optional");
1559
                        }
1560
                        /* Parse the SDP we got, manipulate some things, and generate a new one */
1561
                        sdp_parser_t *parser = sdp_parse(session->stack->s_home, msg->sdp, strlen(msg->sdp), 0);
1562
                        sdp_session_t *parsed_sdp = sdp_session(parser);
1563
                        if(!parsed_sdp) {
1564
                                JANUS_LOG(LOG_ERR, "Error parsing SDP");
1565
                                sdp_parser_free(parser);
1566
                                error_code = JANUS_SIP_ERROR_MISSING_SDP;
1567
                                g_snprintf(error_cause, 512, "Error parsing SDP");
1568
                                goto error;
1569
                        }
1570
                        /* Allocate RTP ports and merge them with the anonymized SDP */
1571
                        if(strstr(msg->sdp, "m=audio")) {
1572
                                JANUS_LOG(LOG_VERB, "Going to negotiate audio...\n");
1573
                                session->media.has_audio = 1;        /* FIXME Maybe we need a better way to signal this */
1574
                        }
1575
                        if(strstr(msg->sdp, "m=video")) {
1576
                                JANUS_LOG(LOG_VERB, "Going to negotiate video...\n");
1577
                                session->media.has_video = 1;        /* FIXME Maybe we need a better way to signal this */
1578
                        }
1579
                        if(janus_sip_allocate_local_ports(session) < 0) {
1580
                                JANUS_LOG(LOG_ERR, "Could not allocate RTP/RTCP ports\n");
1581
                                sdp_parser_free(parser);
1582
                                error_code = JANUS_SIP_ERROR_IO_ERROR;
1583
                                g_snprintf(error_cause, 512, "Could not allocate RTP/RTCP ports");
1584
                                goto error;
1585
                        }
1586
                        char *sdp = janus_sip_sdp_manipulate(session, parsed_sdp);
1587
                        if(sdp == NULL) {
1588
                                JANUS_LOG(LOG_ERR, "Could not allocate RTP/RTCP ports\n");
1589
                                sdp_parser_free(parser);
1590
                                error_code = JANUS_SIP_ERROR_IO_ERROR;
1591
                                g_snprintf(error_cause, 512, "Could not allocate RTP/RTCP ports");
1592
                                goto error;
1593
                        }
1594
                        JANUS_LOG(LOG_VERB, "Prepared SDP for INVITE:\n%s", sdp);
1595
                        /* Send INVITE */
1596
                        if(session->stack->s_nh_i != NULL)
1597
                                nua_handle_destroy(session->stack->s_nh_i);
1598
                        session->stack->s_nh_i = nua_handle(session->stack->s_nua, session, TAG_END());
1599
                        if(session->stack->s_nh_i == NULL) {
1600
                                JANUS_LOG(LOG_WARN, "NUA Handle for INVITE still null??\n");
1601
                                g_free(sdp);
1602
                                sdp_parser_free(parser);
1603
                                error_code = JANUS_SIP_ERROR_LIBSOFIA_ERROR;
1604
                                g_snprintf(error_cause, 512, "Invalid NUA Handle");
1605
                                goto error;
1606
                        }
1607
                        g_atomic_int_set(&session->hangingup, 0);
1608
                        session->status = janus_sip_call_status_inviting;
1609
                        nua_invite(session->stack->s_nh_i,
1610
                                SIPTAG_FROM_STR(session->account.identity),
1611
                                SIPTAG_TO_STR(uri_text),
1612
                                SOATAG_USER_SDP_STR(sdp),
1613
                                NUTAG_PROXY(session->account.proxy),
1614
                                NUTAG_AUTOANSWER(0),
1615
                                TAG_END());
1616
                        g_free(sdp);
1617
                        sdp_parser_free(parser);
1618
                        session->callee = g_strdup(uri_text);
1619
                        if(session->transaction)
1620
                                g_free(session->transaction);
1621
                        session->transaction = msg->transaction ? g_strdup(msg->transaction) : NULL;
1622
                        /* Send an ack back */
1623
                        result = json_object();
1624
                        json_object_set_new(result, "event", json_string("calling"));
1625
                } else if(!strcasecmp(request_text, "accept")) {
1626
                        if(session->status != janus_sip_call_status_invited) {
1627
                                JANUS_LOG(LOG_ERR, "Wrong state (not invited? status=%s)\n", janus_sip_call_status_string(session->status));
1628
                                error_code = JANUS_SIP_ERROR_WRONG_STATE;
1629
                                g_snprintf(error_cause, 512, "Wrong state (not invited? status=%s)", janus_sip_call_status_string(session->status));
1630
                                goto error;
1631
                        }
1632
                        if(session->callee == NULL) {
1633
                                JANUS_LOG(LOG_ERR, "Wrong state (no caller?)\n");
1634
                                error_code = JANUS_SIP_ERROR_WRONG_STATE;
1635
                                g_snprintf(error_cause, 512, "Wrong state (no caller?)");
1636
                                goto error;
1637
                        }
1638
                        json_t *srtp = json_object_get(root, "srtp");
1639
                        gboolean answer_srtp = FALSE;
1640
                        if(srtp) {
1641
                                if(!json_is_string(srtp)) {
1642
                                        JANUS_LOG(LOG_ERR, "Invalid element (srtp should be a string)\n");
1643
                                        error_code = JANUS_SIP_ERROR_INVALID_ELEMENT;
1644
                                        g_snprintf(error_cause, 512, "Invalid element (srtp should be a string)");
1645
                                        goto error;
1646
                                }
1647
                                const char *srtp_text = json_string_value(srtp);
1648
                                if(!strcasecmp(srtp_text, "sdes_optional")) {
1649
                                        /* Negotiate SDES, but make it optional */
1650
                                        answer_srtp = TRUE;
1651
                                } else if(!strcasecmp(srtp_text, "sdes_mandatory")) {
1652
                                        /* Negotiate SDES, and require it */
1653
                                        answer_srtp = TRUE;
1654
                                        session->media.require_srtp = TRUE;
1655
                                } else {
1656
                                        JANUS_LOG(LOG_ERR, "Invalid element (srtp can only be sdes_optional or sdes_mandatory)\n");
1657
                                        error_code = JANUS_SIP_ERROR_INVALID_ELEMENT;
1658
                                        g_snprintf(error_cause, 512, "Invalid element (srtp can only be sdes_optional or sdes_mandatory)");
1659
                                        goto error;
1660
                                }
1661
                        }
1662
                        if(session->media.require_srtp && !session->media.has_srtp_remote) {
1663
                                JANUS_LOG(LOG_ERR, "Can't accept the call: SDES-SRTP required, but caller didn't offer it\n");
1664
                                error_code = JANUS_SIP_ERROR_TOO_STRICT;
1665
                                g_snprintf(error_cause, 512, "Can't accept the call: SDES-SRTP required, but caller didn't offer it");
1666
                                goto error;
1667
                        }
1668
                        answer_srtp = answer_srtp || session->media.has_srtp_remote;
1669
                        /* Any SDP to handle? if not, something's wrong */
1670
                        if(!msg->sdp) {
1671
                                JANUS_LOG(LOG_ERR, "Missing SDP\n");
1672
                                error_code = JANUS_SIP_ERROR_MISSING_SDP;
1673
                                g_snprintf(error_cause, 512, "Missing SDP");
1674
                                goto error;
1675
                        }
1676
                        /* Accept a call from another peer */
1677
                        JANUS_LOG(LOG_VERB, "We're accepting the call from %s\n", session->callee);
1678
                        JANUS_LOG(LOG_VERB, "This is involving a negotiation (%s) as well:\n%s\n", msg->sdp_type, msg->sdp);
1679
                        session->media.has_srtp_local = answer_srtp;
1680
                        if(answer_srtp) {
1681
                                JANUS_LOG(LOG_VERB, "Going to negotiate SDES-SRTP (%s)...\n", session->media.require_srtp ? "mandatory" : "optional");
1682
                        }
1683
                        /* Parse the SDP we got, manipulate some things, and generate a new one */
1684
                        sdp_parser_t *parser = sdp_parse(session->stack->s_home, msg->sdp, strlen(msg->sdp), 0);
1685
                        sdp_session_t *parsed_sdp = sdp_session(parser);
1686
                        if(!parsed_sdp) {
1687
                                JANUS_LOG(LOG_ERR, "Error parsing SDP");
1688
                                sdp_parser_free(parser);
1689
                                error_code = JANUS_SIP_ERROR_MISSING_SDP;
1690
                                g_snprintf(error_cause, 512, "Error parsing SDP");
1691
                                goto error;
1692
                        }
1693
                        /* Allocate RTP ports and merge them with the anonymized SDP */
1694
                        if(strstr(msg->sdp, "m=audio")) {
1695
                                JANUS_LOG(LOG_VERB, "Going to negotiate audio...\n");
1696
                                session->media.has_audio = 1;        /* FIXME Maybe we need a better way to signal this */
1697
                        }
1698
                        if(strstr(msg->sdp, "m=video")) {
1699
                                JANUS_LOG(LOG_VERB, "Going to negotiate video...\n");
1700
                                session->media.has_video = 1;        /* FIXME Maybe we need a better way to signal this */
1701
                        }
1702
                        if(janus_sip_allocate_local_ports(session) < 0) {
1703
                                JANUS_LOG(LOG_ERR, "Could not allocate RTP/RTCP ports\n");
1704
                                sdp_parser_free(parser);
1705
                                error_code = JANUS_SIP_ERROR_IO_ERROR;
1706
                                g_snprintf(error_cause, 512, "Could not allocate RTP/RTCP ports");
1707
                                goto error;
1708
                        }
1709
                        char *sdp = janus_sip_sdp_manipulate(session, parsed_sdp);
1710
                        if(sdp == NULL) {
1711
                                JANUS_LOG(LOG_ERR, "Could not allocate RTP/RTCP ports\n");
1712
                                sdp_parser_free(parser);
1713
                                error_code = JANUS_SIP_ERROR_IO_ERROR;
1714
                                g_snprintf(error_cause, 512, "Could not allocate RTP/RTCP ports");
1715
                                goto error;
1716
                        }
1717
                        JANUS_LOG(LOG_VERB, "Prepared SDP for 200 OK:\n%s", sdp);
1718
                        /* Send 200 OK */
1719
                        g_atomic_int_set(&session->hangingup, 0);
1720
                        session->status = janus_sip_call_status_incall;
1721
                        if(session->stack->s_nh_i == NULL) {
1722
                                JANUS_LOG(LOG_WARN, "NUA Handle for 200 OK still null??\n");
1723
                        }
1724
                        nua_respond(session->stack->s_nh_i,
1725
                                200, sip_status_phrase(200),
1726
                                SOATAG_USER_SDP_STR(sdp),
1727
                                NUTAG_AUTOANSWER(0),
1728
                                TAG_END());
1729
                        g_free(sdp);
1730
                        sdp_parser_free(parser);
1731
                        /* Send an ack back */
1732
                        result = json_object();
1733
                        json_object_set_new(result, "event", json_string("accepted"));
1734
                        /* Start the media */
1735
                        session->media.ready = 1;        /* FIXME Maybe we need a better way to signal this */
1736
                        GError *error = NULL;
1737
                        g_thread_try_new("janus rtp handler", janus_sip_relay_thread, session, &error);
1738
                        if(error != NULL) {
1739
                                JANUS_LOG(LOG_ERR, "Got error %d (%s) trying to launch the RTP/RTCP thread...\n", error->code, error->message ? error->message : "??");
1740
                        }
1741
                } else if(!strcasecmp(request_text, "decline")) {
1742
                        /* Reject an incoming call */
1743
                        if(session->status != janus_sip_call_status_invited) {
1744
                                JANUS_LOG(LOG_ERR, "Wrong state (not invited? status=%s)\n", janus_sip_call_status_string(session->status));
1745
                                /* Ignore */
1746
                                json_decref(root);
1747
                                janus_sip_message_free(msg);
1748
                                continue;
1749
                                //~ g_snprintf(error_cause, 512, "Wrong state (not in a call?)");
1750
                                //~ goto error;
1751
                        }
1752
                        if(session->callee == NULL) {
1753
                                JANUS_LOG(LOG_ERR, "Wrong state (no callee?)\n");
1754
                                error_code = JANUS_SIP_ERROR_WRONG_STATE;
1755
                                g_snprintf(error_cause, 512, "Wrong state (no callee?)");
1756
                                goto error;
1757
                        }
1758
                        session->status = janus_sip_call_status_closing;
1759
                        if(session->stack->s_nh_i == NULL) {
1760
                                JANUS_LOG(LOG_WARN, "NUA Handle for 200 OK still null??\n");
1761
                        }
1762
                        int response_code = 486;
1763
                        json_t *code_json = json_object_get(root, "code");
1764
                        if (code_json && json_is_integer(code_json))
1765
                                response_code = json_integer_value(code_json);
1766
                        if (response_code <= 399) {
1767
                                JANUS_LOG(LOG_WARN, "Invalid SIP response code specified, using 486 to decline call\n");
1768
                                response_code = 486;
1769
                        }
1770
                        nua_respond(session->stack->s_nh_i, response_code, sip_status_phrase(response_code), TAG_END());
1771
                        g_free(session->callee);
1772
                        session->callee = NULL;
1773
                        /* Notify the operation */
1774
                        result = json_object();
1775
                        json_object_set_new(result, "event", json_string("declining"));
1776
                        json_object_set_new(result, "code", json_integer(response_code));
1777
                } else if(!strcasecmp(request_text, "hangup")) {
1778
                        /* Hangup an ongoing call */
1779
                        if(!(session->status == janus_sip_call_status_inviting || session->status == janus_sip_call_status_incall)) {
1780
                                JANUS_LOG(LOG_ERR, "Wrong state (not in a call? status=%s)\n", janus_sip_call_status_string(session->status));
1781
                                /* Ignore */
1782
                                json_decref(root);
1783
                                janus_sip_message_free(msg);
1784
                                continue;
1785
                                //~ g_snprintf(error_cause, 512, "Wrong state (not in a call?)");
1786
                                //~ goto error;
1787
                        }
1788
                        if(session->callee == NULL) {
1789
                                JANUS_LOG(LOG_ERR, "Wrong state (no callee?)\n");
1790
                                error_code = JANUS_SIP_ERROR_WRONG_STATE;
1791
                                g_snprintf(error_cause, 512, "Wrong state (no callee?)");
1792
                                goto error;
1793
                        }
1794
                        session->status = janus_sip_call_status_closing;
1795
                        nua_bye(session->stack->s_nh_i, TAG_END());
1796
                        g_free(session->callee);
1797
                        session->callee = NULL;
1798
                        /* Notify the operation */
1799
                        result = json_object();
1800
                        json_object_set_new(result, "event", json_string("hangingup"));
1801
                } else if(!strcasecmp(request_text, "recording")) {
1802
                        /* Start or stop recording */
1803
                        if(!(session->status == janus_sip_call_status_inviting || session->status == janus_sip_call_status_incall)) {
1804
                                JANUS_LOG(LOG_ERR, "Wrong state (not in a call? status=%s)\n", janus_sip_call_status_string(session->status));
1805
                                g_snprintf(error_cause, 512, "Wrong state (not in a call?)");
1806
                                goto error;
1807
                        }
1808
                        if(session->callee == NULL) {
1809
                                JANUS_LOG(LOG_ERR, "Wrong state (no callee?)\n");
1810
                                error_code = JANUS_SIP_ERROR_WRONG_STATE;
1811
                                g_snprintf(error_cause, 512, "Wrong state (no callee?)");
1812
                                goto error;
1813
                        }
1814
                        json_t *action = json_object_get(root, "action");
1815
                        if(!action) {
1816
                                JANUS_LOG(LOG_ERR, "Missing element (action)\n");
1817
                                error_code = JANUS_SIP_ERROR_MISSING_ELEMENT;
1818
                                g_snprintf(error_cause, 512, "Missing element (action)");
1819
                                goto error;
1820
                        }
1821
                        if(!json_is_string(action)) {
1822
                                JANUS_LOG(LOG_ERR, "Invalid element (action should be a string)\n");
1823
                                error_code = JANUS_SIP_ERROR_INVALID_ELEMENT;
1824
                                g_snprintf(error_cause, 512, "Invalid element (action should be a string)");
1825
                                goto error;
1826
                        }
1827
                        const char *action_text = json_string_value(action);
1828
                        if(strcasecmp(action_text, "start") && strcasecmp(action_text, "stop")) {
1829
                                JANUS_LOG(LOG_ERR, "Invalid action (should be start|stop)\n");
1830
                                error_code = JANUS_SIP_ERROR_INVALID_ELEMENT;
1831
                                g_snprintf(error_cause, 512, "Invalid action (should be start|stop)");
1832
                                goto error;
1833
                        }
1834
                        gboolean record_audio = FALSE, record_video = FALSE,        /* No media is recorded by default */
1835
                                record_peer_audio = FALSE, record_peer_video = FALSE;
1836
                        json_t *audio = json_object_get(root, "audio");
1837
                        if(audio && !json_is_boolean(audio)) {
1838
                                JANUS_LOG(LOG_ERR, "Invalid element (audio should be a boolean)\n");
1839
                                error_code = JANUS_SIP_ERROR_INVALID_ELEMENT;
1840
                                g_snprintf(error_cause, 512, "Invalid value (audio should be a boolean)");
1841
                                goto error;
1842
                        }
1843
                        record_audio = audio ? json_is_true(audio) : FALSE;
1844
                        json_t *video = json_object_get(root, "video");
1845
                        if(video && !json_is_boolean(video)) {
1846
                                JANUS_LOG(LOG_ERR, "Invalid element (video should be a boolean)\n");
1847
                                error_code = JANUS_SIP_ERROR_INVALID_ELEMENT;
1848
                                g_snprintf(error_cause, 512, "Invalid value (video should be a boolean)");
1849
                                goto error;
1850
                        }
1851
                        record_video = video ? json_is_true(video) : FALSE;
1852
                        json_t *peer_audio = json_object_get(root, "peer_audio");
1853
                        if(peer_audio && !json_is_boolean(peer_audio)) {
1854
                                JANUS_LOG(LOG_ERR, "Invalid element (peer_audio should be a boolean)\n");
1855
                                error_code = JANUS_SIP_ERROR_INVALID_ELEMENT;
1856
                                g_snprintf(error_cause, 512, "Invalid value (peer_audio should be a boolean)");
1857
                                goto error;
1858
                        }
1859
                        record_peer_audio = peer_audio ? json_is_true(peer_audio) : FALSE;
1860
                        json_t *peer_video = json_object_get(root, "peer_video");
1861
                        if(peer_video && !json_is_boolean(peer_video)) {
1862
                                JANUS_LOG(LOG_ERR, "Invalid element (peer_video should be a boolean)\n");
1863
                                error_code = JANUS_SIP_ERROR_INVALID_ELEMENT;
1864
                                g_snprintf(error_cause, 512, "Invalid value (peer_video should be a boolean)");
1865
                                goto error;
1866
                        }
1867
                        record_peer_video = peer_video ? json_is_true(peer_video) : FALSE;
1868
                        if(!record_audio && !record_video && !record_peer_audio && !record_peer_video) {
1869
                                JANUS_LOG(LOG_ERR, "Invalid request (at least one of audio, video, peer_audio and peer_video should be true)\n");
1870
                                error_code = JANUS_SIP_ERROR_RECORDING_ERROR;
1871
                                g_snprintf(error_cause, 512, "Invalid request (at least one of audio, video, peer_audio and peer_video should be true)");
1872
                                goto error;
1873
                        }
1874
                        json_t *recfile = json_object_get(root, "filename");
1875
                        if(recfile && !json_is_string(recfile)) {
1876
                                JANUS_LOG(LOG_ERR, "Invalid element (filename should be a string)\n");
1877
                                error_code = JANUS_SIP_ERROR_INVALID_ELEMENT;
1878
                                g_snprintf(error_cause, 512, "Invalid value (filename should be a string)");
1879
                                goto error;
1880
                        }
1881
                        const char *recording_base = json_string_value(recfile);
1882
                        if(!strcasecmp(action_text, "start")) {
1883
                                /* Start recording something */
1884
                                char filename[255];
1885
                                gint64 now = janus_get_real_time();
1886
                                if(record_peer_audio || record_peer_video) {
1887
                                        JANUS_LOG(LOG_INFO, "Starting recording of peer's %s (user %s, call %s)\n",
1888
                                                (record_peer_audio && record_peer_video ? "audio and video" : (record_peer_audio ? "audio" : "video")),
1889
                                                session->account.username, session->transaction);
1890
                                        /* Start recording this peer's audio and/or video */
1891
                                        if(record_peer_audio) {
1892
                                                memset(filename, 0, 255);
1893
                                                if(recording_base) {
1894
                                                        /* Use the filename and path we have been provided */
1895
                                                        g_snprintf(filename, 255, "%s-peer-audio", recording_base);
1896
                                                        session->arc_peer = janus_recorder_create(NULL, 0, filename);
1897
                                                        if(session->arc_peer == NULL) {
1898
                                                                /* FIXME We should notify the fact the recorder could not be created */
1899
                                                                JANUS_LOG(LOG_ERR, "Couldn't open an audio recording file for this peer!\n");
1900
                                                        }
1901
                                                } else {
1902
                                                        /* Build a filename */
1903
                                                        g_snprintf(filename, 255, "sip-%s-%s-%"SCNi64"-peer-audio",
1904
                                                                session->account.username ? session->account.username : "unknown",
1905
                                                                session->transaction ? session->transaction : "unknown",
1906
                                                                now);
1907
                                                        session->arc_peer = janus_recorder_create(NULL, 0, filename);
1908
                                                        if(session->arc_peer == NULL) {
1909
                                                                /* FIXME We should notify the fact the recorder could not be created */
1910
                                                                JANUS_LOG(LOG_ERR, "Couldn't open an audio recording file for this peer!\n");
1911
                                                        }
1912
                                                }
1913
                                        }
1914
                                        if(record_peer_video) {
1915
                                                memset(filename, 0, 255);
1916
                                                if(recording_base) {
1917
                                                        /* Use the filename and path we have been provided */
1918
                                                        g_snprintf(filename, 255, "%s-peer-video", recording_base);
1919
                                                        session->vrc_peer = janus_recorder_create(NULL, 1, filename);
1920
                                                        if(session->vrc_peer == NULL) {
1921
                                                                /* FIXME We should notify the fact the recorder could not be created */
1922
                                                                JANUS_LOG(LOG_ERR, "Couldn't open an video recording file for this peer!\n");
1923
                                                        }
1924
                                                } else {
1925
                                                        /* Build a filename */
1926
                                                        g_snprintf(filename, 255, "sip-%s-%s-%"SCNi64"-peer-video",
1927
                                                                session->account.username ? session->account.username : "unknown",
1928
                                                                session->transaction ? session->transaction : "unknown",
1929
                                                                now);
1930
                                                        session->vrc_peer = janus_recorder_create(NULL, 1, filename);
1931
                                                        if(session->vrc_peer == NULL) {
1932
                                                                /* FIXME We should notify the fact the recorder could not be created */
1933
                                                                JANUS_LOG(LOG_ERR, "Couldn't open an video recording file for this peer!\n");
1934
                                                        }
1935
                                                }
1936
                                                /* TODO We should send a FIR/PLI to this peer... */
1937
                                        }
1938
                                }
1939
                                if(record_audio || record_video) {
1940
                                        /* Start recording the user's audio and/or video */
1941
                                        JANUS_LOG(LOG_INFO, "Starting recording of user's %s (user %s, call %s)\n",
1942
                                                (record_audio && record_video ? "audio and video" : (record_audio ? "audio" : "video")),
1943
                                                session->account.username, session->transaction);
1944
                                        if(record_audio) {
1945
                                                memset(filename, 0, 255);
1946
                                                if(recording_base) {
1947
                                                        /* Use the filename and path we have been provided */
1948
                                                        g_snprintf(filename, 255, "%s-user-audio", recording_base);
1949
                                                        session->arc = janus_recorder_create(NULL, 0, filename);
1950
                                                        if(session->arc == NULL) {
1951
                                                                /* FIXME We should notify the fact the recorder could not be created */
1952
                                                                JANUS_LOG(LOG_ERR, "Couldn't open an audio recording file for this peer!\n");
1953
                                                        }
1954
                                                } else {
1955
                                                        /* Build a filename */
1956
                                                        g_snprintf(filename, 255, "sip-%s-%s-%"SCNi64"-own-audio",
1957
                                                                session->account.username ? session->account.username : "unknown",
1958
                                                                session->transaction ? session->transaction : "unknown",
1959
                                                                now);
1960
                                                        session->arc = janus_recorder_create(NULL, 0, filename);
1961
                                                        if(session->arc == NULL) {
1962
                                                                /* FIXME We should notify the fact the recorder could not be created */
1963
                                                                JANUS_LOG(LOG_ERR, "Couldn't open an audio recording file for this peer!\n");
1964
                                                        }
1965
                                                }
1966
                                        }
1967
                                        if(record_video) {
1968
                                                memset(filename, 0, 255);
1969
                                                if(recording_base) {
1970
                                                        /* Use the filename and path we have been provided */
1971
                                                        g_snprintf(filename, 255, "%s-user-video", recording_base);
1972
                                                        session->vrc = janus_recorder_create(NULL, 1, filename);
1973
                                                        if(session->vrc == NULL) {
1974
                                                                /* FIXME We should notify the fact the recorder could not be created */
1975
                                                                JANUS_LOG(LOG_ERR, "Couldn't open an video recording file for this user!\n");
1976
                                                        }
1977
                                                } else {
1978
                                                        /* Build a filename */
1979
                                                        g_snprintf(filename, 255, "sip-%s-%s-%"SCNi64"-own-video",
1980
                                                                session->account.username ? session->account.username : "unknown",
1981
                                                                session->transaction ? session->transaction : "unknown",
1982
                                                                now);
1983
                                                        session->vrc = janus_recorder_create(NULL, 1, filename);
1984
                                                        if(session->vrc == NULL) {
1985
                                                                /* FIXME We should notify the fact the recorder could not be created */
1986
                                                                JANUS_LOG(LOG_ERR, "Couldn't open an video recording file for this user!\n");
1987
                                                        }
1988
                                                }
1989
                                                /* Send a PLI */
1990
                                                JANUS_LOG(LOG_VERB, "Recording video, sending a PLI to kickstart it\n");
1991
                                                char buf[12];
1992
                                                memset(buf, 0, 12);
1993
                                                janus_rtcp_pli((char *)&buf, 12);
1994
                                                gateway->relay_rtcp(session->handle, 1, buf, 12);
1995
                                        }
1996
                                }
1997
                        } else {
1998
                                /* Stop recording something: notice that this never returns an error, even when we were not recording anything */
1999
                                if(record_audio) {
2000
                                        if(session->arc) {
2001
                                                janus_recorder_close(session->arc);
2002
                                                JANUS_LOG(LOG_INFO, "Closed user's audio recording %s\n", session->arc->filename ? session->arc->filename : "??");
2003
                                                janus_recorder_free(session->arc);
2004
                                        }
2005
                                        session->arc = NULL;
2006
                                }
2007
                                if(record_video) {
2008
                                        if(session->vrc) {
2009
                                                janus_recorder_close(session->vrc);
2010
                                                JANUS_LOG(LOG_INFO, "Closed user's video recording %s\n", session->vrc->filename ? session->vrc->filename : "??");
2011
                                                janus_recorder_free(session->vrc);
2012
                                        }
2013
                                        session->vrc = NULL;
2014
                                }
2015
                                if(record_peer_audio) {
2016
                                        if(session->arc_peer) {
2017
                                                janus_recorder_close(session->arc_peer);
2018
                                                JANUS_LOG(LOG_INFO, "Closed peer's audio recording %s\n", session->arc_peer->filename ? session->arc_peer->filename : "??");
2019
                                                janus_recorder_free(session->arc_peer);
2020
                                        }
2021
                                        session->arc_peer = NULL;
2022
                                }
2023
                                if(record_peer_video) {
2024
                                        if(session->vrc_peer) {
2025
                                                janus_recorder_close(session->vrc_peer);
2026
                                                JANUS_LOG(LOG_INFO, "Closed peer's video recording %s\n", session->vrc_peer->filename ? session->vrc_peer->filename : "??");
2027
                                                janus_recorder_free(session->vrc_peer);
2028
                                        }
2029
                                        session->vrc_peer = NULL;
2030
                                }
2031
                        }
2032
                        /* Notify the result */
2033
                        result = json_object();
2034
                        json_object_set_new(result, "event", json_string("recordingupdated"));
2035
                } else if(!strcasecmp(request_text, "dtmf_info")) {
2036
                        /* Send DMTF tones using SIP INFO
2037
                         * (https://tools.ietf.org/html/draft-kaplan-dispatch-info-dtmf-package-00)
2038
                         */
2039
                        if(!(session->status == janus_sip_call_status_inviting || session->status == janus_sip_call_status_incall)) {
2040
                                JANUS_LOG(LOG_ERR, "Wrong state (not in a call? status=%s)\n", janus_sip_call_status_string(session->status));
2041
                                g_snprintf(error_cause, 512, "Wrong state (not in a call?)");
2042
                                goto error;
2043
                        }
2044
                        if(session->callee == NULL) {
2045
                                JANUS_LOG(LOG_ERR, "Wrong state (no callee?)\n");
2046
                                error_code = JANUS_SIP_ERROR_WRONG_STATE;
2047
                                g_snprintf(error_cause, 512, "Wrong state (no callee?)");
2048
                                goto error;
2049
                        }
2050
                        json_t *digit = json_object_get(root, "digit");
2051
                        if(!digit) {
2052
                                JANUS_LOG(LOG_ERR, "Missing element (digit)\n");
2053
                                error_code = JANUS_SIP_ERROR_MISSING_ELEMENT;
2054
                                g_snprintf(error_cause, 512, "Missing element (digit)");
2055
                                goto error;
2056
                        }
2057
                        if(!json_is_string(digit)) {
2058
                                JANUS_LOG(LOG_ERR, "Invalid element (digit should be a string)\n");
2059
                                error_code = JANUS_SIP_ERROR_INVALID_ELEMENT;
2060
                                g_snprintf(error_cause, 512, "Invalid element (digit should be a string)");
2061
                                goto error;
2062
                        }
2063
                        const char *digit_text = json_string_value(digit);
2064
                        if(strlen(digit_text) != 1) {
2065
                                JANUS_LOG(LOG_ERR, "Invalid element (digit should be one character))\n");
2066
                                error_code = JANUS_SIP_ERROR_INVALID_ELEMENT;
2067
                                g_snprintf(error_cause, 512, "Invalid element (digit should be one character)");
2068
                                goto error;
2069
                        }
2070
                        int duration_ms = 0;
2071
                        json_t *duration = json_object_get(root, "duration");
2072
                        if(duration && !json_is_integer(duration)) {
2073
                                JANUS_LOG(LOG_ERR, "Invalid element (duration should be an integer)\n");
2074
                                error_code = JANUS_SIP_ERROR_INVALID_ELEMENT;
2075
                                g_snprintf(error_cause, 512, "Invalid element (duration should be an integer)");
2076
                                goto error;
2077
                        }
2078
                        duration_ms = duration ? json_integer_value(duration) : 0;
2079
                        if (duration_ms <= 0 || duration_ms > 5000) {
2080
                                duration_ms = 160; /* default value */
2081
                        }
2082

    
2083
                        char payload[64];
2084
                        g_snprintf(payload, sizeof(payload), "Signal=%s\r\nDuration=%d", digit_text, duration_ms);
2085
                        nua_info(session->stack->s_nh_i,
2086
                                SIPTAG_CONTENT_TYPE_STR("application/dtmf-relay"),
2087
                                SIPTAG_PAYLOAD_STR(payload),
2088
                                TAG_END());
2089
                } else {
2090
                        JANUS_LOG(LOG_ERR, "Unknown request (%s)\n", request_text);
2091
                        error_code = JANUS_SIP_ERROR_INVALID_REQUEST;
2092
                        g_snprintf(error_cause, 512, "Unknown request (%s)", request_text);
2093
                        goto error;
2094
                }
2095

    
2096
                json_decref(root);
2097
                /* Prepare JSON event */
2098
                json_t *event = json_object();
2099
                json_object_set_new(event, "sip", json_string("event"));
2100
                if(result != NULL)
2101
                        json_object_set_new(event, "result", result);
2102
                char *event_text = json_dumps(event, JSON_INDENT(3) | JSON_PRESERVE_ORDER);
2103
                json_decref(event);
2104
                JANUS_LOG(LOG_VERB, "Pushing event: %s\n", event_text);
2105
                int ret = gateway->push_event(msg->handle, &janus_sip_plugin, msg->transaction, event_text, sdp_type, sdp);
2106
                JANUS_LOG(LOG_VERB, "  >> %d (%s)\n", ret, janus_get_api_error(ret));
2107
                g_free(event_text);
2108
                if(sdp)
2109
                        g_free(sdp);
2110
                janus_sip_message_free(msg);
2111
                continue;
2112

    
2113
error:
2114
                {
2115
                        if(root != NULL)
2116
                                json_decref(root);
2117
                        /* Prepare JSON error event */
2118
                        json_t *event = json_object();
2119
                        json_object_set_new(event, "sip", json_string("event"));
2120
                        json_object_set_new(event, "error_code", json_integer(error_code));
2121
                        json_object_set_new(event, "error", json_string(error_cause));
2122
                        char *event_text = json_dumps(event, JSON_INDENT(3) | JSON_PRESERVE_ORDER);
2123
                        json_decref(event);
2124
                        JANUS_LOG(LOG_VERB, "Pushing event: %s\n", event_text);
2125
                        int ret = gateway->push_event(msg->handle, &janus_sip_plugin, msg->transaction, event_text, NULL, NULL);
2126
                        JANUS_LOG(LOG_VERB, "  >> %d (%s)\n", ret, janus_get_api_error(ret));
2127
                        g_free(event_text);
2128
                        janus_sip_message_free(msg);
2129
                }
2130
        }
2131
        g_free(error_cause);
2132
        JANUS_LOG(LOG_VERB, "Leaving SIP handler thread\n");
2133
        return NULL;
2134
}
2135

    
2136

    
2137
/* Sofia callbacks */
2138
void janus_sip_sofia_callback(nua_event_t event, int status, char const *phrase, nua_t *nua, nua_magic_t *magic, nua_handle_t *nh, nua_hmagic_t *hmagic, sip_t const *sip, tagi_t tags[])
2139
{
2140
        janus_sip_session *session = (janus_sip_session *)magic;
2141
        ssip_t *ssip = session->stack;
2142
        switch (event) {
2143
        /* Status or Error Indications */
2144
                case nua_i_active:
2145
                        JANUS_LOG(LOG_VERB, "[%s][%s]: %d %s\n", session->account.username, nua_event_name(event), status, phrase ? phrase : "??");
2146
                        break;
2147
                case nua_i_error:
2148
                        JANUS_LOG(LOG_VERB, "[%s][%s]: %d %s\n", session->account.username, nua_event_name(event), status, phrase ? phrase : "??");
2149
                        break;
2150
                case nua_i_fork:
2151
                        JANUS_LOG(LOG_VERB, "[%s][%s]: %d %s\n", session->account.username, nua_event_name(event), status, phrase ? phrase : "??");
2152
                        break;
2153
                case nua_i_media_error:
2154
                        JANUS_LOG(LOG_VERB, "[%s][%s]: %d %s\n", session->account.username, nua_event_name(event), status, phrase ? phrase : "??");
2155
                        break;
2156
                case nua_i_subscription:
2157
                        JANUS_LOG(LOG_VERB, "[%s][%s]: %d %s\n", session->account.username, nua_event_name(event), status, phrase ? phrase : "??");
2158
                        break;
2159
                case nua_i_state:
2160
                        JANUS_LOG(LOG_VERB, "[%s][%s]: %d %s\n", session->account.username, nua_event_name(event), status, phrase ? phrase : "??");
2161
                        tagi_t const *ti = tl_find(tags, nutag_callstate);
2162
                        enum nua_callstate callstate = ti ? ti->t_value : -1;
2163
                        /* There are several call states, but we only care about the terminated state
2164
                         * in order to send the 'hangup' event (assuming this is the right session, of course).
2165
                         * http://sofia-sip.sourceforge.net/refdocs/nua/nua__tag_8h.html#a516dc237722dc8ca4f4aa3524b2b444b
2166
                         */
2167
                        if(callstate == nua_callstate_terminated &&
2168
                                        (session->stack->s_nh_i == nh || session->stack->s_nh_i == NULL)) {
2169
                                session->status = janus_sip_call_status_idle;
2170
                                session->stack->s_nh_i = NULL;
2171
                                json_t *call = json_object();
2172
                                json_object_set_new(call, "sip", json_string("event"));
2173
                                json_t *calling = json_object();
2174
                                json_object_set_new(calling, "event", json_string("hangup"));
2175
                                json_object_set_new(calling, "code", json_integer(status));
2176
                                json_object_set_new(calling, "reason", json_string(phrase ? phrase : "???"));
2177
                                json_object_set_new(call, "result", calling);
2178
                                char *call_text = json_dumps(call, JSON_INDENT(3) | JSON_PRESERVE_ORDER);
2179
                                json_decref(call);
2180
                                JANUS_LOG(LOG_VERB, "Pushing event: %s\n", call_text);
2181
                                int ret = gateway->push_event(session->handle, &janus_sip_plugin, session->transaction, call_text, NULL, NULL);
2182
                                JANUS_LOG(LOG_VERB, "  >> %d (%s)\n", ret, janus_get_api_error(ret));
2183
                                g_free(call_text);
2184
                                /* Get rid of any PeerConnection that may have been set up */
2185
                                if(session->transaction)
2186
                                        g_free(session->transaction);
2187
                                session->transaction = NULL;
2188
                                gateway->close_pc(session->handle);
2189
                        }
2190
                        break;
2191
                case nua_i_terminated:
2192
                        JANUS_LOG(LOG_VERB, "[%s][%s]: %d %s\n", session->account.username, nua_event_name(event), status, phrase ? phrase : "??");
2193
                        break;
2194
        /* SIP requests */
2195
                case nua_i_ack:
2196
                        JANUS_LOG(LOG_VERB, "[%s][%s]: %d %s\n", session->account.username, nua_event_name(event), status, phrase ? phrase : "??");
2197
                        break;
2198
                case nua_i_outbound:
2199
                        JANUS_LOG(LOG_VERB, "[%s][%s]: %d %s\n", session->account.username, nua_event_name(event), status, phrase ? phrase : "??");
2200
                        break;
2201
                case nua_i_bye: {
2202
                        JANUS_LOG(LOG_VERB, "[%s][%s]: %d %s\n", session->account.username, nua_event_name(event), status, phrase ? phrase : "??");
2203
                        break;
2204
                }
2205
                case nua_i_cancel: {
2206
                        JANUS_LOG(LOG_VERB, "[%s][%s]: %d %s\n", session->account.username, nua_event_name(event), status, phrase ? phrase : "??");
2207
                        break;
2208
                }
2209
                case nua_i_invite: {
2210
                        JANUS_LOG(LOG_VERB, "[%s][%s]: %d %s\n", session->account.username, nua_event_name(event), status, phrase ? phrase : "??");
2211
                        if(ssip == NULL) {
2212
                                JANUS_LOG(LOG_ERR, "\tInvalid SIP stack\n");
2213
                                nua_respond(nh, 500, sip_status_phrase(500), TAG_END());
2214
                                break;
2215
                        }
2216
                        sdp_parser_t *parser = sdp_parse(ssip->s_home, sip->sip_payload->pl_data, sip->sip_payload->pl_len, 0);
2217
                        if(!sdp_session(parser)) {
2218
                                JANUS_LOG(LOG_ERR, "\tError parsing SDP!\n");
2219
                                nua_respond(nh, 488, sip_status_phrase(488), TAG_END());
2220
                                sdp_parser_free(parser);
2221
                                break;
2222
                        }
2223
                        if(session->stack->s_nh_i != NULL) {
2224
                                if(session->stack->s_nh_i == nh) {
2225
                                        /* re-INVITE, we don't support those. */
2226
                                        nua_respond(nh, 488, sip_status_phrase(488), TAG_END());
2227
                                } else if(session->status >= janus_sip_call_status_inviting) {
2228
                                        /* Busy with another call */
2229
                                        JANUS_LOG(LOG_VERB, "\tAlready in a call (busy, status=%s)\n", janus_sip_call_status_string(session->status));
2230
                                        nua_respond(nh, 486, sip_status_phrase(486), TAG_END());
2231
                                        /* Notify the web app about the missed invite */
2232
                                        json_t *missed = json_object();
2233
                                        json_object_set_new(missed, "sip", json_string("event"));
2234
                                        json_t *result = json_object();
2235
                                        json_object_set_new(result, "event", json_string("missed_call"));
2236
                                        char *caller_text = url_as_string(session->stack->s_home, sip->sip_from->a_url);
2237
                                        json_object_set_new(result, "caller", json_string(caller_text));
2238
                                        su_free(session->stack->s_home, caller_text);
2239
                                        if (sip->sip_from && sip->sip_from->a_display) {
2240
                                                json_object_set_new(result, "displayname", json_string(sip->sip_from->a_display));
2241
                                        }
2242
                                        json_object_set_new(missed, "result", result);
2243
                                        char *missed_text = json_dumps(missed, JSON_INDENT(3) | JSON_PRESERVE_ORDER);
2244
                                        json_decref(missed);
2245
                                        JANUS_LOG(LOG_VERB, "Pushing event to peer: %s\n", missed_text);
2246
                                        int ret = gateway->push_event(session->handle, &janus_sip_plugin, session->transaction, missed_text, NULL, NULL);
2247
                                        JANUS_LOG(LOG_VERB, "  >> %d (%s)\n", ret, janus_get_api_error(ret));
2248
                                        g_free(missed_text);
2249
                                }
2250
                                sdp_parser_free(parser);
2251
                                break;
2252
                        }
2253
                        /* New incoming call */
2254
                        session->callee = g_strdup(url_as_string(session->stack->s_home, sip->sip_from->a_url));
2255
                        session->status = janus_sip_call_status_invited;
2256
                        /* Clean up SRTP stuff from before first, in case it's still needed */
2257
                        janus_sip_srtp_cleanup(session);
2258
                        /* Parse SDP */
2259
                        char *fixed_sdp = g_strdup(sip->sip_payload->pl_data);
2260
                        JANUS_LOG(LOG_VERB, "Someone is inviting us in a call:\n%s", sip->sip_payload->pl_data);
2261
                        sdp_session_t *sdp = sdp_session(parser);
2262
                        janus_sip_sdp_process(session, sdp);
2263
                        /* Send SDP to the browser */
2264
                        json_t *call = json_object();
2265
                        json_object_set_new(call, "sip", json_string("event"));
2266
                        json_t *calling = json_object();
2267
                        json_object_set_new(calling, "event", json_string("incomingcall"));
2268
                        json_object_set_new(calling, "username", json_string(session->callee));
2269
                        if(sip->sip_from && sip->sip_from->a_display) {
2270
                                json_object_set_new(calling, "displayname", json_string(sip->sip_from->a_display));
2271
                        }
2272
                        if(session->media.has_srtp_remote) {
2273
                                /* FIXME Maybe a true/false instead? */
2274
                                json_object_set_new(calling, "srtp", json_string(session->media.require_srtp ? "sdes_mandatory" : "sdes_optional"));
2275
                        }
2276
                        json_object_set_new(call, "result", calling);
2277
                        char *call_text = json_dumps(call, JSON_INDENT(3) | JSON_PRESERVE_ORDER);
2278
                        json_decref(call);
2279
                        JANUS_LOG(LOG_VERB, "Pushing event to peer: %s\n", call_text);
2280
                        int ret = gateway->push_event(session->handle, &janus_sip_plugin, session->transaction, call_text, "offer", fixed_sdp);
2281
                        JANUS_LOG(LOG_VERB, "  >> %d (%s)\n", ret, janus_get_api_error(ret));
2282
                        g_free(call_text);
2283
                        g_free(fixed_sdp);
2284
                        /* Send a Ringing back */
2285
                        nua_respond(nh, 180, sip_status_phrase(180), TAG_END());
2286
                        session->stack->s_nh_i = nh;
2287
                        break;
2288
                }
2289
                case nua_i_options:
2290
                        JANUS_LOG(LOG_VERB, "[%s][%s]: %d %s\n", session->account.username, nua_event_name(event), status, phrase ? phrase : "??");
2291
                        /* FIXME Should we handle this message? for now we reply with a 405 Method Not Implemented */
2292
                        nua_respond(nh, 405, sip_status_phrase(405), TAG_END());
2293
                        break;
2294
        /* Responses */
2295
                case nua_r_get_params:
2296
                        JANUS_LOG(LOG_VERB, "[%s][%s]: %d %s\n", session->account.username, nua_event_name(event), status, phrase ? phrase : "??");
2297
                        break;
2298
                case nua_r_set_params:
2299
                        JANUS_LOG(LOG_VERB, "[%s][%s]: %d %s\n", session->account.username, nua_event_name(event), status, phrase ? phrase : "??");
2300
                        break;
2301
                case nua_r_notifier:
2302
                        JANUS_LOG(LOG_VERB, "[%s][%s]: %d %s\n", session->account.username, nua_event_name(event), status, phrase ? phrase : "??");
2303
                        break;
2304
                case nua_r_shutdown:
2305
                        JANUS_LOG(LOG_VERB, "[%s][%s]: %d %s\n", session->account.username, nua_event_name(event), status, phrase ? phrase : "??");
2306
                        if(status < 200 && !g_atomic_int_get(&stopping)) {
2307
                                /* shutdown in progress -> return */
2308
                                break;
2309
                        }
2310
                        if(ssip != NULL) {
2311
                                /* end the event loop. su_root_run() will return */
2312
                                su_root_break(ssip->s_root);
2313
                        }
2314
                        break;
2315
                case nua_r_terminate:
2316
                        JANUS_LOG(LOG_VERB, "[%s][%s]: %d %s\n", session->account.username, nua_event_name(event), status, phrase ? phrase : "??");
2317
                        break;
2318
        /* SIP responses */
2319
                case nua_r_bye:
2320
                        JANUS_LOG(LOG_VERB, "[%s][%s]: %d %s\n", session->account.username, nua_event_name(event), status, phrase ? phrase : "??");
2321
                        break;
2322
                case nua_r_cancel:
2323
                        JANUS_LOG(LOG_VERB, "[%s][%s]: %d %s\n", session->account.username, nua_event_name(event), status, phrase ? phrase : "??");
2324
                        break;
2325
                case nua_r_info:
2326
                        JANUS_LOG(LOG_VERB, "[%s][%s]: %d %s\n", session->account.username, nua_event_name(event), status, phrase ? phrase : "??");
2327
                        break;
2328
                case nua_r_invite: {
2329
                        JANUS_LOG(LOG_VERB, "[%s][%s]: %d %s\n", session->account.username, nua_event_name(event), status, phrase ? phrase : "??");
2330
                        if(status < 200) {
2331
                                /* Not ready yet (FIXME May this be pranswer?? we don't handle it yet...) */
2332
                                break;
2333
                        } else if(status == 401 || status == 407) {
2334
                                char auth[256];
2335
                                const char* scheme;
2336
                                const char* realm;
2337
                                if(status == 401) {
2338
                                         /* Get scheme/realm from 401 error */
2339
                                        sip_www_authenticate_t const* www_auth = sip->sip_www_authenticate;
2340
                                        scheme = www_auth->au_scheme;
2341
                                        realm = msg_params_find(www_auth->au_params, "realm=");
2342
                                } else {
2343
                                         /* Get scheme/realm from 407 error, proxy-auth */
2344
                                        sip_proxy_authenticate_t const* proxy_auth = sip->sip_proxy_authenticate;
2345
                                        scheme = proxy_auth->au_scheme;
2346
                                        realm = msg_params_find(proxy_auth->au_params, "realm=");
2347
                                }
2348
                                memset(auth, 0, sizeof(auth));
2349
                                g_snprintf(auth, sizeof(auth), "%s%s:%s:%s:%s%s",
2350
                                        session->account.secret_type == janus_sip_secret_type_hashed ? "HA1+" : "",
2351
                                        scheme,
2352
                                        realm,
2353
                                        session->account.authuser ? session->account.authuser : "null",
2354
                                        session->account.secret_type == janus_sip_secret_type_hashed ? "HA1+" : "",
2355
                                        session->account.secret ? session->account.secret : "null");
2356
                                JANUS_LOG(LOG_VERB, "\t%s\n", auth);
2357
                                /* Authenticate */
2358
                                nua_authenticate(nh,
2359
                                        NUTAG_AUTH(auth),
2360
                                        TAG_END());
2361
                                break;
2362
                        } else if(status >= 400) {
2363
                                break;
2364
                        }
2365
                        if(ssip == NULL) {
2366
                                JANUS_LOG(LOG_ERR, "\tInvalid SIP stack\n");
2367
                                nua_respond(nh, 500, sip_status_phrase(500), TAG_END());
2368
                                break;
2369
                        }
2370
                        sdp_parser_t *parser = sdp_parse(ssip->s_home, sip->sip_payload->pl_data, sip->sip_payload->pl_len, 0);
2371
                        if(!sdp_session(parser)) {
2372
                                JANUS_LOG(LOG_ERR, "\tError parsing SDP!\n");
2373
                                nua_respond(nh, 488, sip_status_phrase(488), TAG_END());
2374
                                sdp_parser_free(parser);
2375
                                break;
2376
                        }
2377
                        JANUS_LOG(LOG_VERB, "Peer accepted our call:\n%s", sip->sip_payload->pl_data);
2378
                        session->status = janus_sip_call_status_incall;
2379
                        char *fixed_sdp = g_strdup(sip->sip_payload->pl_data);
2380
                        sdp_session_t *sdp = sdp_session(parser);
2381
                        janus_sip_sdp_process(session, sdp);
2382
                        /* If we asked for SRTP and are not getting it, fail */
2383
                        if(session->media.require_srtp && !session->media.has_srtp_remote) {
2384
                                JANUS_LOG(LOG_ERR, "\tWe asked for mandatory SRTP but didn't get any in the reply!\n");
2385
                                sdp_parser_free(parser);
2386
                                g_free(fixed_sdp);
2387
                                /* Hangup immediately */
2388
                                session->status = janus_sip_call_status_closing;
2389
                                nua_bye(nh, TAG_END());
2390
                                g_free(session->callee);
2391
                                session->callee = NULL;
2392
                                break;
2393
                        }
2394
                        session->media.ready = 1;        /* FIXME Maybe we need a better way to signal this */
2395
                        GError *error = NULL;
2396
                        g_thread_try_new("janus rtp handler", janus_sip_relay_thread, session, &error);
2397
                        if(error != NULL) {
2398
                                JANUS_LOG(LOG_ERR, "Got error %d (%s) trying to launch the RTP/RTCP thread...\n", error->code, error->message ? error->message : "??");
2399
                        }
2400
                        /* Send SDP to the browser */
2401
                        json_t *call = json_object();
2402
                        json_object_set_new(call, "sip", json_string("event"));
2403
                        json_t *calling = json_object();
2404
                        json_object_set_new(calling, "event", json_string("accepted"));
2405
                        json_object_set_new(calling, "username", json_string(session->callee));
2406
                        json_object_set_new(call, "result", calling);
2407
                        char *call_text = json_dumps(call, JSON_INDENT(3) | JSON_PRESERVE_ORDER);
2408
                        json_decref(call);
2409
                        JANUS_LOG(LOG_VERB, "Pushing event to peer: %s\n", call_text);
2410
                        int ret = gateway->push_event(session->handle, &janus_sip_plugin, session->transaction, call_text, "answer", fixed_sdp);
2411
                        JANUS_LOG(LOG_VERB, "  >> %d (%s)\n", ret, janus_get_api_error(ret));
2412
                        g_free(call_text);
2413
                        g_free(fixed_sdp);
2414
                        break;
2415
                }
2416
                case nua_r_register: {
2417
                        JANUS_LOG(LOG_VERB, "[%s][%s]: %d %s\n", session->account.username, nua_event_name(event), status, phrase ? phrase : "??");
2418
                        if(status == 200) {
2419
                                if(session->account.registration_status < janus_sip_registration_status_registered)
2420
                                        session->account.registration_status = janus_sip_registration_status_registered;
2421
                                JANUS_LOG(LOG_VERB, "Successfully registered\n");
2422
                                /* Notify the browser */
2423
                                json_t *call = json_object();
2424
                                json_object_set_new(call, "sip", json_string("event"));
2425
                                json_t *calling = json_object();
2426
                                json_object_set_new(calling, "event", json_string("registered"));
2427
                                json_object_set_new(calling, "username", json_string(session->account.username));
2428
                                json_object_set_new(calling, "register_sent", json_string("true"));
2429
                                json_object_set_new(call, "result", calling);
2430
                                char *call_text = json_dumps(call, JSON_INDENT(3) | JSON_PRESERVE_ORDER);
2431
                                json_decref(call);
2432
                                JANUS_LOG(LOG_VERB, "Pushing event: %s\n", call_text);
2433
                                int ret = gateway->push_event(session->handle, &janus_sip_plugin, session->transaction, call_text, NULL, NULL);
2434
                                JANUS_LOG(LOG_VERB, "  >> %d (%s)\n", ret, janus_get_api_error(ret));
2435
                                g_free(call_text);
2436
                        } else if(status == 401) {
2437
                                /* Get scheme/realm from 401 error */
2438
                                sip_www_authenticate_t const* www_auth = sip->sip_www_authenticate;
2439
                                char const* scheme = www_auth->au_scheme;
2440
                                const char* realm = msg_params_find(www_auth->au_params, "realm=");
2441
                                char auth[256];
2442
                                memset(auth, 0, sizeof(auth));
2443
                                g_snprintf(auth, sizeof(auth), "%s%s:%s:%s:%s%s",
2444
                                        session->account.secret_type == janus_sip_secret_type_hashed ? "HA1+" : "",
2445
                                        scheme,
2446
                                        realm,
2447
                                        session->account.authuser ? session->account.authuser : "null",
2448
                                        session->account.secret_type == janus_sip_secret_type_hashed ? "HA1+" : "",
2449
                                        session->account.secret);
2450
                                JANUS_LOG(LOG_VERB, "\t%s\n", auth);
2451
                                /* Authenticate */
2452
                                nua_authenticate(nh,
2453
                                        NUTAG_AUTH(auth),
2454
                                        TAG_END());
2455
                        } else if(status >= 400) {
2456
                                /* Authentication failed? */
2457
                                session->account.registration_status = janus_sip_registration_status_failed;
2458
                                /* Tell the browser... */
2459
                                json_t *event = json_object();
2460
                                json_object_set_new(event, "sip", json_string("event"));
2461
                                json_t *result = json_object();
2462
                                json_object_set_new(result, "event", json_string("registration_failed"));
2463
                                json_object_set_new(result, "code", json_integer(status));
2464
                                json_object_set_new(result, "reason", json_string(phrase ? phrase : ""));
2465
                                json_object_set_new(event, "result", result);
2466
                                char *event_text = json_dumps(event, JSON_INDENT(3) | JSON_PRESERVE_ORDER);
2467
                                json_decref(event);
2468
                                JANUS_LOG(LOG_VERB, "Pushing event: %s\n", event_text);
2469
                                int ret = gateway->push_event(session->handle, &janus_sip_plugin, session->transaction, event_text, NULL, NULL);
2470
                                JANUS_LOG(LOG_VERB, "  >> %d (%s)\n", ret, janus_get_api_error(ret));
2471
                                g_free(event_text);
2472
                        }
2473
                        break;
2474
                }
2475
                default:
2476
                        /* unknown event -> print out error message */
2477
                        JANUS_LOG(LOG_ERR, "Unknown event %d (%s)\n", event, nua_event_name(event));
2478
                        break;
2479
        }
2480
}
2481

    
2482
void janus_sip_sdp_process(janus_sip_session *session, sdp_session_t *sdp) {
2483
        if(!session || !sdp)
2484
                return;
2485
        /* c= */
2486
        if(sdp->sdp_connection && sdp->sdp_connection->c_address) {
2487
                g_free(session->media.remote_ip);
2488
                session->media.remote_ip = g_strdup(sdp->sdp_connection->c_address);
2489
                JANUS_LOG(LOG_VERB, "  >> Media connection:\n");
2490
                JANUS_LOG(LOG_VERB, "       %s\n", session->media.remote_ip);
2491
        }
2492
        JANUS_LOG(LOG_VERB, "  >> Media lines:\n");
2493
        sdp_media_t *m = sdp->sdp_media;
2494
        while(m) {
2495
                session->media.require_srtp = session->media.require_srtp || (m->m_proto_name && !strcasecmp(m->m_proto_name, "RTP/SAVP"));
2496
                if(m->m_type == sdp_media_audio) {
2497
                        JANUS_LOG(LOG_VERB, "       Audio: %lu\n", m->m_port);
2498
                        if(m->m_port) {
2499
                                session->media.has_audio = 1;
2500
                                session->media.remote_audio_rtp_port = m->m_port;
2501
                                session->media.remote_audio_rtcp_port = m->m_port+1;        /* FIXME We're assuming RTCP is on the next port */
2502
                        }
2503
                } else if(m->m_type == sdp_media_video) {
2504
                        JANUS_LOG(LOG_VERB, "       Video: %lu\n", m->m_port);
2505
                        if(m->m_port) {
2506
                                session->media.has_video = 1;
2507
                                session->media.remote_video_rtp_port = m->m_port;
2508
                                session->media.remote_video_rtcp_port = m->m_port+1;        /* FIXME We're assuming RTCP is on the next port */
2509
                        }
2510
                } else {
2511
                        JANUS_LOG(LOG_WARN, "       Unsupported media line (not audio/video)\n");
2512
                        m = m->m_next;
2513
                        continue;
2514
                }
2515
                JANUS_LOG(LOG_VERB, "       Media connections:\n");
2516
                if(m->m_connections) {
2517
                        sdp_connection_t *c = m->m_connections;
2518
                        while(c) {
2519
                                if(c->c_address) {
2520
                                        g_free(session->media.remote_ip);
2521
                                        session->media.remote_ip = g_strdup(c->c_address);
2522
                                        JANUS_LOG(LOG_VERB, "         [%s]\n", session->media.remote_ip);
2523
                                }
2524
                                c = c->c_next;
2525
                        }
2526
                }
2527
                JANUS_LOG(LOG_VERB, "       Media RTP maps:\n");
2528
                sdp_rtpmap_t *r = m->m_rtpmaps;
2529
                while(r) {
2530
                        JANUS_LOG(LOG_VERB, "         [%u] %s\n", r->rm_pt, r->rm_encoding);
2531
                        r = r->rm_next;
2532
                }
2533
                JANUS_LOG(LOG_VERB, "       Media attributes:\n");
2534
                sdp_attribute_t *a = m->m_attributes;
2535
                while(a) {
2536
                        if(a->a_name) {
2537
                                if(!strcasecmp(a->a_name, "rtpmap")) {
2538
                                        JANUS_LOG(LOG_VERB, "         RTP Map:     %s\n", a->a_value);
2539
                                } else if(!strcasecmp(a->a_name, "crypto")) {
2540
                                        JANUS_LOG(LOG_VERB, "         Crypto:      %s\n", a->a_value);
2541
                                        if(m->m_type == sdp_media_audio || m->m_type == sdp_media_video) {
2542
                                                gint32 tag = 0;
2543
                                                int suite;
2544
                                                char crypto[40];
2545
                                                /* FIXME inline can be more complex than that, and we're currently only offering SHA1_80 */
2546
                                                int res = sscanf(a->a_value, "%"SCNi32" AES_CM_128_HMAC_SHA1_%2d inline:%40s",
2547
                                                        &tag, &suite, crypto);
2548
                                                if(res != 3) {
2549
                                                        JANUS_LOG(LOG_WARN, "Failed to parse crypto line, ignoring... %s\n", a->a_value);
2550
                                                } else {
2551
                                                        gboolean video = (m->m_type == sdp_media_video);
2552
                                                        int current_suite = video ? session->media.video_srtp_suite_in : session->media.audio_srtp_suite_in;
2553
                                                        if(current_suite == 0) {
2554
                                                                if(video)
2555
                                                                        session->media.video_srtp_suite_in = suite;
2556
                                                                else
2557
                                                                        session->media.audio_srtp_suite_in = suite;
2558
                                                                janus_sip_srtp_set_remote(session, video, crypto, suite);
2559
                                                                session->media.has_srtp_remote = TRUE;
2560
                                                        } else {
2561
                                                                JANUS_LOG(LOG_WARN, "We already configured a %s crypto context (AES_CM_128_HMAC_SHA1_%d), skipping additional crypto line\n",
2562
                                                                        video ? "video" : "audio", current_suite);
2563
                                                        }
2564
                                                }
2565
                                        }
2566
                                }
2567
                        }
2568
                        a = a->a_next;
2569
                }
2570
                m = m->m_next;
2571
        }
2572
}
2573

    
2574
char *janus_sip_sdp_manipulate(janus_sip_session *session, sdp_session_t *sdp) {
2575
        if(!session || !session->stack || !sdp)
2576
                return NULL;
2577
        /* Placeholders for later */
2578
        sdp_attribute_t crypto_audio = {
2579
                .a_size = sizeof(sdp_attribute_t),
2580
                .a_name = "crypto",
2581
                .a_value = "audio"
2582
        };
2583
        sdp_attribute_t crypto_video = {
2584
                .a_size = sizeof(sdp_attribute_t),
2585
                .a_name = "crypto",
2586
                .a_value = "video"
2587
        };
2588
        /* Start replacing stuff */
2589
        if(sdp->sdp_connection && sdp->sdp_connection->c_address) {
2590
                sdp->sdp_connection->c_address = local_ip;
2591
        }
2592
        JANUS_LOG(LOG_VERB, "Setting protocol to %s\n", session->media.require_srtp ? "RTP/SAVP" : "RTP/AVP");
2593
        sdp_media_t *m = sdp->sdp_media;
2594
        while(m) {
2595
                m->m_proto = session->media.require_srtp ? sdp_proto_srtp : sdp_proto_rtp;
2596
                m->m_proto_name = session->media.require_srtp ? "RTP/SAVP" : "RTP/AVP";
2597
                if(m->m_type == sdp_media_audio) {
2598
                        m->m_port = session->media.local_audio_rtp_port;
2599
                        if(session->media.has_srtp_local) {
2600
                                sdp_attribute_append(&m->m_attributes, &crypto_audio);
2601
                        }
2602
                } else if(m->m_type == sdp_media_video) {
2603
                        m->m_port = session->media.local_video_rtp_port;
2604
                        if(session->media.has_srtp_local) {
2605
                                sdp_attribute_append(&m->m_attributes, &crypto_video);
2606
                        }
2607
                }
2608
                if(m->m_connections) {
2609
                        sdp_connection_t *c = m->m_connections;
2610
                        while(c) {
2611
                                c->c_address = local_ip;
2612
                                c = c->c_next;
2613
                        }
2614
                }
2615
                m = m->m_next;
2616
        }
2617
        /* Generate a SDP string out of our changes */
2618
        char buf[2048];
2619
        sdp_printer_t *printer = sdp_print(session->stack->s_home, sdp, buf, 2048, 0);
2620
        if(!sdp_message(printer)) {
2621
                sdp_printer_free(printer);
2622
                return NULL;
2623
        }
2624
        sdp_printer_free(printer);
2625
        char *new_sdp = g_strdup(buf);
2626
        /* If any crypto placeholer was there, fix that */
2627
        if(session->media.has_srtp_local) {
2628
                if(session->media.has_audio) {
2629
                        char *crypto = NULL;
2630
                        session->media.audio_srtp_suite_out = 80;
2631
                        janus_sip_srtp_set_local(session, FALSE, &crypto);
2632
                        /* FIXME 32? 80? Both? */
2633
                        char cryptoline[100];
2634
                        g_snprintf(cryptoline, 100, "a=crypto:1 AES_CM_128_HMAC_SHA1_80 inline:%s", crypto);
2635
                        g_free(crypto);
2636
                        new_sdp = janus_string_replace(new_sdp, "a=crypto:audio", cryptoline);
2637
                }
2638
                if(session->media.has_video) {
2639
                        char *crypto = NULL;
2640
                        session->media.video_srtp_suite_out = 80;
2641
                        janus_sip_srtp_set_local(session, TRUE, &crypto);
2642
                        /* FIXME 32? 80? Both? */
2643
                        char cryptoline[100];
2644
                        g_snprintf(cryptoline, 100, "a=crypto:1 AES_CM_128_HMAC_SHA1_80 inline:%s", crypto);
2645
                        g_free(crypto);
2646
                        new_sdp = janus_string_replace(new_sdp, "a=crypto:video", cryptoline);
2647
                }
2648
        }
2649
        return new_sdp;
2650
}
2651

    
2652
/* Bind local RTP/RTCP sockets */
2653
static int janus_sip_allocate_local_ports(janus_sip_session *session) {
2654
        if(session == NULL) {
2655
                JANUS_LOG(LOG_ERR, "Invalid session\n");
2656
                return -1;
2657
        }
2658
        /* Reset status */
2659
        if(session->media.audio_rtp_fd != -1) {
2660
                close(session->media.audio_rtp_fd);
2661
                session->media.audio_rtp_fd = -1;
2662
        }
2663
        if(session->media.audio_rtcp_fd != -1) {
2664
                close(session->media.audio_rtcp_fd);
2665
                session->media.audio_rtcp_fd = -1;
2666
        }
2667
        session->media.local_audio_rtp_port = 0;
2668
        session->media.local_audio_rtcp_port = 0;
2669
        session->media.audio_ssrc = 0;
2670
        if(session->media.video_rtp_fd != -1) {
2671
                close(session->media.video_rtp_fd);
2672
                session->media.video_rtp_fd = -1;
2673
        }
2674
        if(session->media.video_rtcp_fd != -1) {
2675
                close(session->media.video_rtcp_fd);
2676
                session->media.video_rtcp_fd = -1;
2677
        }
2678
        session->media.local_video_rtp_port = 0;
2679
        session->media.local_video_rtcp_port = 0;
2680
        session->media.video_ssrc = 0;
2681
        /* Start */
2682
        int attempts = 100;        /* FIXME Don't retry forever */
2683
        if(session->media.has_audio) {
2684
                JANUS_LOG(LOG_VERB, "Allocating audio ports:\n");
2685
                struct sockaddr_in audio_rtp_address, audio_rtcp_address;
2686
                while(session->media.local_audio_rtp_port == 0 || session->media.local_audio_rtcp_port == 0) {
2687
                        if(attempts == 0)        /* Too many failures */
2688
                                return -1;
2689
                        if(session->media.audio_rtp_fd == -1) {
2690
                                session->media.audio_rtp_fd = socket(AF_INET, SOCK_DGRAM, 0);
2691
                        }
2692
                        if(session->media.audio_rtcp_fd == -1) {
2693
                                session->media.audio_rtcp_fd = socket(AF_INET, SOCK_DGRAM, 0);
2694
                        }
2695
                        int rtp_port = g_random_int_range(10000, 60000);        /* FIXME Should this be configurable? */
2696
                        if(rtp_port % 2)
2697
                                rtp_port++;        /* Pick an even port for RTP */
2698
                        audio_rtp_address.sin_family = AF_INET;
2699
                        audio_rtp_address.sin_port = htons(rtp_port);
2700
                        inet_pton(AF_INET, local_ip, &audio_rtp_address.sin_addr.s_addr);
2701
                        if(bind(session->media.audio_rtp_fd, (struct sockaddr *)(&audio_rtp_address), sizeof(struct sockaddr)) < 0) {
2702
                                JANUS_LOG(LOG_ERR, "Bind failed for audio RTP (port %d), trying a different one...\n", rtp_port);
2703
                                attempts--;
2704
                                continue;
2705
                        }
2706
                        JANUS_LOG(LOG_VERB, "Audio RTP listener bound to port %d\n", rtp_port);
2707
                        int rtcp_port = rtp_port+1;
2708
                        audio_rtcp_address.sin_family = AF_INET;
2709
                        audio_rtcp_address.sin_port = htons(rtcp_port);
2710
                        inet_pton(AF_INET, local_ip, &audio_rtcp_address.sin_addr.s_addr);
2711
                        if(bind(session->media.audio_rtcp_fd, (struct sockaddr *)(&audio_rtcp_address), sizeof(struct sockaddr)) < 0) {
2712
                                JANUS_LOG(LOG_ERR, "Bind failed for audio RTCP (port %d), trying a different one...\n", rtcp_port);
2713
                                /* RTP socket is not valid anymore, reset it */
2714
                                close(session->media.audio_rtp_fd);
2715
                                session->media.audio_rtp_fd = -1;
2716
                                attempts--;
2717
                                continue;
2718
                        }
2719
                        JANUS_LOG(LOG_VERB, "Audio RTCP listener bound to port %d\n", rtcp_port);
2720
                        session->media.local_audio_rtp_port = rtp_port;
2721
                        session->media.local_audio_rtcp_port = rtcp_port;
2722
                }
2723
        }
2724
        if(session->media.has_video) {
2725
                JANUS_LOG(LOG_VERB, "Allocating video ports:\n");
2726
                struct sockaddr_in video_rtp_address, video_rtcp_address;
2727
                while(session->media.local_video_rtp_port == 0 || session->media.local_video_rtcp_port == 0) {
2728
                        if(attempts == 0)        /* Too many failures */
2729
                                return -1;
2730
                        if(session->media.video_rtp_fd == -1) {
2731
                                session->media.video_rtp_fd = socket(AF_INET, SOCK_DGRAM, 0);
2732
                        }
2733
                        if(session->media.video_rtcp_fd == -1) {
2734
                                session->media.video_rtcp_fd = socket(AF_INET, SOCK_DGRAM, 0);
2735
                        }
2736
                        int rtp_port = g_random_int_range(10000, 60000);        /* FIXME Should this be configurable? */
2737
                        if(rtp_port % 2)
2738
                                rtp_port++;        /* Pick an even port for RTP */
2739
                        video_rtp_address.sin_family = AF_INET;
2740
                        video_rtp_address.sin_port = htons(rtp_port);
2741
                        inet_pton(AF_INET, local_ip, &video_rtp_address.sin_addr.s_addr);
2742
                        if(bind(session->media.video_rtp_fd, (struct sockaddr *)(&video_rtp_address), sizeof(struct sockaddr)) < 0) {
2743
                                JANUS_LOG(LOG_ERR, "Bind failed for video RTP (port %d), trying a different one...\n", rtp_port);
2744
                                attempts--;
2745
                                continue;
2746
                        }
2747
                        JANUS_LOG(LOG_VERB, "Video RTP listener bound to port %d\n", rtp_port);
2748
                        int rtcp_port = rtp_port+1;
2749
                        video_rtcp_address.sin_family = AF_INET;
2750
                        video_rtcp_address.sin_port = htons(rtcp_port);
2751
                        inet_pton(AF_INET, local_ip, &video_rtcp_address.sin_addr.s_addr);
2752
                        if(bind(session->media.video_rtcp_fd, (struct sockaddr *)(&video_rtcp_address), sizeof(struct sockaddr)) < 0) {
2753
                                JANUS_LOG(LOG_ERR, "Bind failed for video RTCP (port %d), trying a different one...\n", rtcp_port);
2754
                                /* RTP socket is not valid anymore, reset it */
2755
                                close(session->media.video_rtp_fd);
2756
                                session->media.video_rtp_fd = -1;
2757
                                attempts--;
2758
                                continue;
2759
                        }
2760
                        JANUS_LOG(LOG_VERB, "Video RTCP listener bound to port %d\n", rtcp_port);
2761
                        session->media.local_video_rtp_port = rtp_port;
2762
                        session->media.local_video_rtcp_port = rtcp_port;
2763
                }
2764
        }
2765
        return 0;
2766
}
2767

    
2768
/* Thread to relay RTP/RTCP frames coming from the SIP peer */
2769
static void *janus_sip_relay_thread(void *data) {
2770
        janus_sip_session *session = (janus_sip_session *)data;
2771
        if(!session || !session->account.username || !session->callee) {
2772
                g_thread_unref(g_thread_self());
2773
                return NULL;
2774
        }
2775
        JANUS_LOG(LOG_VERB, "Starting relay thread (%s <--> %s)\n", session->account.username, session->callee);
2776

    
2777
        gboolean have_server_ip = TRUE;
2778
        struct sockaddr_in server_addr;
2779
        memset(&server_addr, 0, sizeof(server_addr));
2780
        server_addr.sin_family = AF_INET;
2781
        if((inet_aton(session->media.remote_ip, &server_addr.sin_addr)) <= 0) {        /* Not a numeric IP... */
2782
                struct hostent *host = gethostbyname(session->media.remote_ip);        /* ...resolve name */
2783
                if(!host) {
2784
                        JANUS_LOG(LOG_ERR, "[SIP-%s] Couldn't get host (%s)\n", session->account.username, session->media.remote_ip);
2785
                        have_server_ip = FALSE;
2786
                } else {
2787
                        server_addr.sin_addr = *(struct in_addr *)host->h_addr_list;
2788
                }
2789
        }
2790

    
2791
        /* Connect peers (FIXME This pretty much sucks right now) */
2792
        if(have_server_ip && session->media.remote_audio_rtp_port) {
2793
                server_addr.sin_port = htons(session->media.remote_audio_rtp_port);
2794
                if(connect(session->media.audio_rtp_fd, (struct sockaddr *)&server_addr, sizeof(struct sockaddr)) == -1) {
2795
                        JANUS_LOG(LOG_ERR, "[SIP-%s] Couldn't connect audio RTP? (%s:%d)\n", session->account.username, session->media.remote_ip, session->media.remote_audio_rtp_port);
2796
                        JANUS_LOG(LOG_ERR, "[SIP-%s]   -- %d (%s)\n", session->account.username, errno, strerror(errno));
2797
                }
2798
        }
2799
        if(have_server_ip && session->media.remote_audio_rtcp_port) {
2800
                server_addr.sin_port = htons(session->media.remote_audio_rtcp_port);
2801
                if(connect(session->media.audio_rtcp_fd, (struct sockaddr *)&server_addr, sizeof(struct sockaddr)) == -1) {
2802
                        JANUS_LOG(LOG_ERR, "[SIP-%s] Couldn't connect audio RTCP? (%s:%d)\n", session->account.username, session->media.remote_ip, session->media.remote_audio_rtcp_port);
2803
                        JANUS_LOG(LOG_ERR, "[SIP-%s]   -- %d (%s)\n", session->account.username, errno, strerror(errno));
2804
                }
2805
        }
2806
        if(have_server_ip && session->media.remote_video_rtp_port) {
2807
                server_addr.sin_port = htons(session->media.remote_video_rtp_port);
2808
                if(connect(session->media.video_rtp_fd, (struct sockaddr *)&server_addr, sizeof(struct sockaddr)) == -1) {
2809
                        JANUS_LOG(LOG_ERR, "[SIP-%s] Couldn't connect video RTP? (%s:%d)\n", session->account.username, session->media.remote_ip, session->media.remote_video_rtp_port);
2810
                        JANUS_LOG(LOG_ERR, "[SIP-%s]   -- %d (%s)\n", session->account.username, errno, strerror(errno));
2811
                }
2812
        }
2813
        if(have_server_ip && session->media.remote_video_rtcp_port) {
2814
                server_addr.sin_port = htons(session->media.remote_video_rtcp_port);
2815
                if(connect(session->media.video_rtcp_fd, (struct sockaddr *)&server_addr, sizeof(struct sockaddr)) == -1) {
2816
                        JANUS_LOG(LOG_ERR, "[SIP-%s] Couldn't connect video RTCP? (%s:%d)\n", session->account.username, session->media.remote_ip, session->media.remote_video_rtcp_port);
2817
                        JANUS_LOG(LOG_ERR, "[SIP-%s]   -- %d (%s)\n", session->account.username, errno, strerror(errno));
2818
                }
2819
        }
2820

    
2821
        if(!session->callee) {
2822
                JANUS_LOG(LOG_VERB, "[SIP-%s] Leaving thread, no callee...\n", session->account.username);
2823
                g_thread_unref(g_thread_self());
2824
                return NULL;
2825
        }
2826
        /* File descriptors */
2827
        socklen_t addrlen;
2828
        struct sockaddr_in remote;
2829
        int resfd = 0, bytes = 0;
2830
        struct pollfd fds[4];
2831
        char buffer[1500];
2832
        memset(buffer, 0, 1500);
2833
        /* Loop */
2834
        int num = 0;
2835
        gboolean goon = TRUE;
2836
        while(goon && session != NULL && !session->destroyed &&
2837
                        session->status > janus_sip_call_status_idle &&
2838
                        session->status < janus_sip_call_status_closing) {        /* FIXME We need a per-call watchdog as well */
2839
                /* Prepare poll */
2840
                num = 0;
2841
                if(session->media.audio_rtp_fd != -1) {
2842
                        fds[num].fd = session->media.audio_rtp_fd;
2843
                        fds[num].events = POLLIN;
2844
                        fds[num].revents = 0;
2845
                        num++;
2846
                }
2847
                if(session->media.audio_rtcp_fd != -1) {
2848
                        fds[num].fd = session->media.audio_rtcp_fd;
2849
                        fds[num].events = POLLIN;
2850
                        fds[num].revents = 0;
2851
                        num++;
2852
                }
2853
                if(session->media.video_rtp_fd != -1) {
2854
                        fds[num].fd = session->media.video_rtp_fd;
2855
                        fds[num].events = POLLIN;
2856
                        fds[num].revents = 0;
2857
                        num++;
2858
                }
2859
                if(session->media.video_rtcp_fd != -1) {
2860
                        fds[num].fd = session->media.video_rtcp_fd;
2861
                        fds[num].events = POLLIN;
2862
                        fds[num].revents = 0;
2863
                        num++;
2864
                }
2865
                /* Wait for some data */
2866
                resfd = poll(fds, num, 1000);
2867
                if(resfd < 0) {
2868
                        JANUS_LOG(LOG_ERR, "[SIP-%s] Error polling...\n", session->account.username);
2869
                        JANUS_LOG(LOG_ERR, "[SIP-%s]   -- %d (%s)\n", session->account.username, errno, strerror(errno));
2870
                        break;
2871
                } else if(resfd == 0) {
2872
                        /* No data, keep going */
2873
                        continue;
2874
                }
2875
                if(session == NULL || session->destroyed ||
2876
                                session->status <= janus_sip_call_status_idle ||
2877
                                session->status >= janus_sip_call_status_closing)
2878
                        break;
2879
                int i = 0;
2880
                for(i=0; i<num; i++) {
2881
                        if(fds[i].revents & (POLLERR | POLLHUP)) {
2882
                                /* Socket error? */
2883
                                JANUS_LOG(LOG_ERR, "[SIP-%s] Error polling: %s...\n", session->account.username,
2884
                                        fds[i].revents & POLLERR ? "POLLERR" : "POLLHUP");
2885
                                JANUS_LOG(LOG_ERR, "[SIP-%s]   -- %d (%s)\n", session->account.username, errno, strerror(errno));
2886
                                goon = FALSE;        /* Can we assume it's pretty much over, after a POLLERR? */
2887
                                /* FIXME Simulate a "hangup" coming from the browser */
2888
                                janus_sip_message *msg = g_malloc0(sizeof(janus_sip_message));
2889
                                msg->handle = session->handle;
2890
                                msg->message = g_strdup("{\"request\":\"hangup\"}");
2891
                                msg->transaction = NULL;
2892
                                msg->sdp_type = NULL;
2893
                                msg->sdp = NULL;
2894
                                g_async_queue_push(messages, msg);
2895
                                break;
2896
                        } else if(fds[i].revents & POLLIN) {
2897
                                /* Got an RTP/RTCP packet */
2898
                                if(session->media.audio_rtp_fd != -1 && fds[i].fd == session->media.audio_rtp_fd) {
2899
                                        /* Got something audio (RTP) */
2900
                                        addrlen = sizeof(remote);
2901
                                        bytes = recvfrom(session->media.audio_rtp_fd, buffer, 1500, 0, (struct sockaddr*)&remote, &addrlen);
2902
                                        //~ JANUS_LOG(LOG_VERB, "************************\nGot %d bytes on the audio RTP channel...\n", bytes);
2903
                                        //~ rtp_header_t *rtp = (rtp_header_t *)buffer;
2904
                                        //~ JANUS_LOG(LOG_VERB, " ... parsed RTP packet (ssrc=%u, pt=%u, seq=%u, ts=%u)...\n",
2905
                                                //~ ntohl(rtp->ssrc), rtp->type, ntohs(rtp->seq_number), ntohl(rtp->timestamp));
2906
                                        if(session->media.audio_ssrc_peer == 0) {
2907
                                                rtp_header *header = (rtp_header *)buffer;
2908
                                                session->media.audio_ssrc_peer = ntohl(header->ssrc);
2909
                                                JANUS_LOG(LOG_VERB, "Got SIP peer audio SSRC: %"SCNu32"\n", session->media.audio_ssrc_peer);
2910
                                        }
2911
                                        /* Is this SRTP? */
2912
                                        if(session->media.has_srtp_remote) {
2913
                                                int buflen = bytes;
2914
                                                err_status_t res = srtp_unprotect(session->media.audio_srtp_in, buffer, &buflen);
2915
                                                if(res != err_status_ok && res != err_status_replay_fail && res != err_status_replay_old) {
2916
                                                        rtp_header *header = (rtp_header *)buffer;
2917
                                                        guint32 timestamp = ntohl(header->timestamp);
2918
                                                        guint16 seq = ntohs(header->seq_number);
2919
                                                        JANUS_LOG(LOG_ERR, "[SIP-%s] Audio SRTP unprotect error: %s (len=%d-->%d, ts=%"SCNu32", seq=%"SCNu16")\n",
2920
                                                                session->account.username, janus_sip_get_srtp_error(res), bytes, buflen, timestamp, seq);
2921
                                                        continue;
2922
                                                }
2923
                                                bytes = buflen;
2924
                                        }
2925
                                        /* Save the frame if we're recording */
2926
                                        if(session->arc_peer)
2927
                                                janus_recorder_save_frame(session->arc_peer, buffer, bytes);
2928
                                        /* Relay to browser */
2929
                                        gateway->relay_rtp(session->handle, 0, buffer, bytes);
2930
                                        continue;
2931
                                } else if(session->media.audio_rtcp_fd != -1 && fds[i].fd == session->media.audio_rtcp_fd) {
2932
                                        /* Got something audio (RTCP) */
2933
                                        addrlen = sizeof(remote);
2934
                                        bytes = recvfrom(session->media.audio_rtcp_fd, buffer, 1500, 0, (struct sockaddr*)&remote, &addrlen);
2935
                                        //~ JANUS_LOG(LOG_VERB, "************************\nGot %d bytes on the audio RTCP channel...\n", bytes);
2936
                                        /* Is this SRTCP? */
2937
                                        if(session->media.has_srtp_remote) {
2938
                                                int buflen = bytes;
2939
                                                err_status_t res = srtp_unprotect_rtcp(session->media.audio_srtp_in, buffer, &buflen);
2940
                                                if(res != err_status_ok && res != err_status_replay_fail && res != err_status_replay_old) {
2941
                                                        JANUS_LOG(LOG_ERR, "[SIP-%s] Audio SRTCP unprotect error: %s (len=%d-->%d)\n",
2942
                                                                session->account.username, janus_sip_get_srtp_error(res), bytes, buflen);
2943
                                                        continue;
2944
                                                }
2945
                                                bytes = buflen;
2946
                                        }
2947
                                        /* Relay to browser */
2948
                                        gateway->relay_rtcp(session->handle, 0, buffer, bytes);
2949
                                        continue;
2950
                                } else if(session->media.video_rtp_fd != -1 && fds[i].fd == session->media.video_rtp_fd) {
2951
                                        /* Got something video (RTP) */
2952
                                        addrlen = sizeof(remote);
2953
                                        bytes = recvfrom(session->media.video_rtp_fd, buffer, 1500, 0, (struct sockaddr*)&remote, &addrlen);
2954
                                        //~ JANUS_LOG(LOG_VERB, "************************\nGot %d bytes on the video RTP channel...\n", bytes);
2955
                                        //~ rtp_header_t *rtp = (rtp_header_t *)buffer;
2956
                                        //~ JANUS_LOG(LOG_VERB, " ... parsed RTP packet (ssrc=%u, pt=%u, seq=%u, ts=%u)...\n",
2957
                                                //~ ntohl(rtp->ssrc), rtp->type, ntohs(rtp->seq_number), ntohl(rtp->timestamp));
2958
                                        if(session->media.video_ssrc_peer == 0) {
2959
                                                rtp_header *header = (rtp_header *)buffer;
2960
                                                session->media.video_ssrc_peer = ntohl(header->ssrc);
2961
                                                JANUS_LOG(LOG_VERB, "Got SIP peer video SSRC: %"SCNu32"\n", session->media.video_ssrc_peer);
2962
                                        }
2963
                                        /* Is this SRTP? */
2964
                                        if(session->media.has_srtp_remote) {
2965
                                                int buflen = bytes;
2966
                                                err_status_t res = srtp_unprotect(session->media.video_srtp_in, buffer, &buflen);
2967
                                                if(res != err_status_ok && res != err_status_replay_fail && res != err_status_replay_old) {
2968
                                                        rtp_header *header = (rtp_header *)buffer;
2969
                                                        guint32 timestamp = ntohl(header->timestamp);
2970
                                                        guint16 seq = ntohs(header->seq_number);
2971
                                                        JANUS_LOG(LOG_ERR, "[SIP-%s] Video SRTP unprotect error: %s (len=%d-->%d, ts=%"SCNu32", seq=%"SCNu16")\n",
2972
                                                                session->account.username, janus_sip_get_srtp_error(res), bytes, buflen, timestamp, seq);
2973
                                                        continue;
2974
                                                }
2975
                                                bytes = buflen;
2976
                                        }
2977
                                        /* Save the frame if we're recording */
2978
                                        if(session->vrc_peer)
2979
                                                janus_recorder_save_frame(session->vrc_peer, buffer, bytes);
2980
                                        /* Relay to browser */
2981
                                        gateway->relay_rtp(session->handle, 1, buffer, bytes);
2982
                                        continue;
2983
                                } else if(session->media.video_rtcp_fd != -1 && fds[i].fd == session->media.video_rtcp_fd) {
2984
                                        /* Got something video (RTCP) */
2985
                                        addrlen = sizeof(remote);
2986
                                        bytes = recvfrom(session->media.video_rtcp_fd, buffer, 1500, 0, (struct sockaddr*)&remote, &addrlen);
2987
                                        //~ JANUS_LOG(LOG_VERB, "************************\nGot %d bytes on the video RTCP channel...\n", bytes);
2988
                                        /* Is this SRTCP? */
2989
                                        if(session->media.has_srtp_remote) {
2990
                                                int buflen = bytes;
2991
                                                err_status_t res = srtp_unprotect_rtcp(session->media.video_srtp_in, buffer, &buflen);
2992
                                                if(res != err_status_ok && res != err_status_replay_fail && res != err_status_replay_old) {
2993
                                                        JANUS_LOG(LOG_ERR, "[SIP-%s] Video SRTP unprotect error: %s (len=%d-->%d)\n",
2994
                                                                session->account.username, janus_sip_get_srtp_error(res), bytes, buflen);
2995
                                                        continue;
2996
                                                }
2997
                                                bytes = buflen;
2998
                                        }
2999
                                        /* Relay to browser */
3000
                                        gateway->relay_rtcp(session->handle, 1, buffer, bytes);
3001
                                        continue;
3002
                                }
3003
                        }
3004
                }
3005
        }
3006
        if(session->media.audio_rtp_fd != -1) {
3007
                close(session->media.audio_rtp_fd);
3008
                session->media.audio_rtp_fd = -1;
3009
        }
3010
        if(session->media.audio_rtcp_fd != -1) {
3011
                close(session->media.audio_rtcp_fd);
3012
                session->media.audio_rtcp_fd = -1;
3013
        }
3014
        session->media.local_audio_rtp_port = 0;
3015
        session->media.local_audio_rtcp_port = 0;
3016
        session->media.audio_ssrc = 0;
3017
        if(session->media.video_rtp_fd != -1) {
3018
                close(session->media.video_rtp_fd);
3019
                session->media.video_rtp_fd = -1;
3020
        }
3021
        if(session->media.video_rtcp_fd != -1) {
3022
                close(session->media.video_rtcp_fd);
3023
                session->media.video_rtcp_fd = -1;
3024
        }
3025
        session->media.local_video_rtp_port = 0;
3026
        session->media.local_video_rtcp_port = 0;
3027
        session->media.video_ssrc = 0;
3028
        /* Clean up SRTP stuff, if needed */
3029
        janus_sip_srtp_cleanup(session);
3030
        /* Done */
3031
        JANUS_LOG(LOG_VERB, "Leaving SIP relay thread\n");
3032
        g_thread_unref(g_thread_self());
3033
        return NULL;
3034
}
3035

    
3036

    
3037
/* Sofia Event thread */
3038
gpointer janus_sip_sofia_thread(gpointer user_data) {
3039
        janus_sip_session *session = (janus_sip_session *)user_data;
3040
        if(session == NULL || session->account.username == NULL) {
3041
                g_thread_unref(g_thread_self());
3042
                return NULL;
3043
        }
3044
        JANUS_LOG(LOG_VERB, "Joining sofia loop thread (%s)...\n", session->account.username);
3045
        session->stack = g_malloc0(sizeof(ssip_t));
3046
        session->stack->session = session;
3047
        session->stack->s_nua = NULL;
3048
        session->stack->s_nh_r = NULL;
3049
        session->stack->s_nh_i = NULL;
3050
        session->stack->s_root = su_root_create(session->stack);
3051
        su_home_init(session->stack->s_home);
3052
        JANUS_LOG(LOG_VERB, "Setting up sofia stack (sip:%s@%s)\n", session->account.username, local_ip);
3053
        char sip_url[128];
3054
        char sips_url[128];
3055
        char *ipv6;
3056
        ipv6 = strstr(local_ip, ":");
3057
        g_snprintf(sip_url, sizeof(sip_url), "sip:%s%s%s:*", ipv6 ? "[" : "", local_ip, ipv6 ? "]" : "");
3058
        g_snprintf(sips_url, sizeof(sips_url), "sips:%s%s%s:*", ipv6 ? "[" : "", local_ip, ipv6 ? "]" : "");
3059
        char outbound_options[256] = "use-rport no-validate";
3060
        if(keepalive_interval > 0)
3061
                g_strlcat(outbound_options, " options-keepalive", sizeof(outbound_options));
3062
        if(!behind_nat)
3063
                g_strlcat(outbound_options, " no-natify", sizeof(outbound_options));
3064
        session->stack->s_nua = nua_create(session->stack->s_root,
3065
                                janus_sip_sofia_callback,
3066
                                session,
3067
                                SIPTAG_ALLOW_STR("INVITE, ACK, BYE, CANCEL, OPTIONS"),
3068
                                NUTAG_M_USERNAME(session->account.username),
3069
                                NUTAG_URL(sip_url),
3070
                                TAG_IF(session->account.sips, NUTAG_SIPS_URL(sips_url)),
3071
                                SIPTAG_USER_AGENT_STR(user_agent),
3072
                                NUTAG_KEEPALIVE(keepalive_interval * 1000),        /* Sofia expects it in milliseconds */
3073
                                NUTAG_OUTBOUND(outbound_options),
3074
                                SIPTAG_SUPPORTED(NULL),
3075
                                TAG_NULL());
3076
        su_root_run(session->stack->s_root);
3077
        /* When we get here, we're done */
3078
        nua_destroy(session->stack->s_nua);
3079
        su_root_destroy(session->stack->s_root);
3080
        session->stack->s_root = NULL;
3081
        su_home_deinit(session->stack->s_home);
3082
        su_home_unref(session->stack->s_home);
3083
        su_deinit();
3084
        if (session->stack) {
3085
                g_free(session->stack);
3086
                session->stack = NULL;
3087
        }
3088
        //~ stop = 1;
3089
        JANUS_LOG(LOG_VERB, "Leaving sofia loop thread...\n");
3090
        g_thread_unref(g_thread_self());
3091
        /* Cleaning up and removing the session is done in a lazy way */
3092
        janus_mutex_lock(&sessions_mutex);
3093
        old_sessions = g_list_append(old_sessions, session);
3094
        janus_mutex_unlock(&sessions_mutex);
3095
        return NULL;
3096
}