Statistics
| Branch: | Revision:

janus-gateway / plugins / janus_sip.c @ 1aee055e

History | View | Annotate | Download (127 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                        6
80
#define JANUS_SIP_VERSION_STRING        "0.0.6"
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
/* Parameter validation */
137
static struct janus_json_parameter request_parameters[] = {
138
        {"request", JSON_STRING, JANUS_JSON_PARAM_REQUIRED}
139
};
140
static struct janus_json_parameter register_parameters[] = {
141
        {"type", JSON_STRING, 0},
142
        {"send_register", JANUS_JSON_BOOL, 0},
143
        {"sips", JANUS_JSON_BOOL, 0},
144
        {"username", JSON_STRING, 0},
145
        {"secret", JSON_STRING, 0},
146
        {"ha1_secret", JSON_STRING, 0},
147
        {"authuser", JSON_STRING, 0}
148
};
149
static struct janus_json_parameter proxy_parameters[] = {
150
        {"proxy", JSON_STRING, 0}
151
};
152
static struct janus_json_parameter call_parameters[] = {
153
        {"uri", JSON_STRING, JANUS_JSON_PARAM_REQUIRED},
154
        {"autoack", JANUS_JSON_BOOL, 0},
155
        {"headers", JSON_OBJECT, 0},
156
        {"srtp", JSON_STRING, 0}
157
};
158
static struct janus_json_parameter accept_parameters[] = {
159
        {"srtp", JSON_STRING, 0}
160
};
161
static struct janus_json_parameter recording_parameters[] = {
162
        {"action", JSON_STRING, JANUS_JSON_PARAM_REQUIRED},
163
        {"audio", JANUS_JSON_BOOL, 0},
164
        {"video", JANUS_JSON_BOOL, 0},
165
        {"peer_audio", JANUS_JSON_BOOL, 0},
166
        {"peer_video", JANUS_JSON_BOOL, 0},
167
        {"filename", JSON_STRING, 0}
168
};
169
static struct janus_json_parameter dtmf_info_parameters[] = {
170
        {"digit", JSON_STRING, JANUS_JSON_PARAM_REQUIRED},
171
        {"duration", JSON_INTEGER, JANUS_JSON_PARAM_POSITIVE}
172
};
173

    
174
/* Useful stuff */
175
static volatile gint initialized = 0, stopping = 0;
176
static janus_callbacks *gateway = NULL;
177

    
178
static char local_ip[INET6_ADDRSTRLEN];
179
static int keepalive_interval = 120;
180
static gboolean behind_nat = FALSE;
181
static char *user_agent;
182
#define JANUS_DEFAULT_REGISTER_TTL        3600
183
static int register_ttl = JANUS_DEFAULT_REGISTER_TTL;
184

    
185
static GThread *handler_thread;
186
static GThread *watchdog;
187
static void *janus_sip_handler(void *data);
188

    
189
typedef struct janus_sip_message {
190
        janus_plugin_session *handle;
191
        char *transaction;
192
        char *message;
193
        char *sdp_type;
194
        char *sdp;
195
} janus_sip_message;
196
static GAsyncQueue *messages = NULL;
197
static janus_sip_message exit_message;
198

    
199
static void janus_sip_message_free(janus_sip_message *msg) {
200
        if(!msg || msg == &exit_message)
201
                return;
202

    
203
        msg->handle = NULL;
204

    
205
        g_free(msg->transaction);
206
        msg->transaction = NULL;
207
        g_free(msg->message);
208
        msg->message = NULL;
209
        g_free(msg->sdp_type);
210
        msg->sdp_type = NULL;
211
        g_free(msg->sdp);
212
        msg->sdp = NULL;
213

    
214
        g_free(msg);
215
}
216

    
217

    
218
typedef enum {
219
        janus_sip_registration_status_disabled = -2,
220
        janus_sip_registration_status_failed = -1,
221
        janus_sip_registration_status_unregistered = 0,
222
        janus_sip_registration_status_registering,
223
        janus_sip_registration_status_registered,
224
        janus_sip_registration_status_unregistering,
225
} janus_sip_registration_status;
226

    
227
static const char *janus_sip_registration_status_string(janus_sip_registration_status status) {
228
        switch(status) {
229
                case janus_sip_registration_status_disabled:
230
                        return "disabled";
231
                case janus_sip_registration_status_failed:
232
                        return "failed";
233
                case janus_sip_registration_status_unregistered:
234
                        return "unregistered";
235
                case janus_sip_registration_status_registering:
236
                        return "registering";
237
                case janus_sip_registration_status_registered:
238
                        return "registered";
239
                case janus_sip_registration_status_unregistering:
240
                        return "unregistering";
241
                default:
242
                        return "unknown";
243
        }
244
}
245

    
246

    
247
typedef enum {
248
        janus_sip_call_status_idle = 0,
249
        janus_sip_call_status_inviting,
250
        janus_sip_call_status_invited,
251
        janus_sip_call_status_incall,
252
        janus_sip_call_status_closing,
253
} janus_sip_call_status;
254

    
255
static const char *janus_sip_call_status_string(janus_sip_call_status status) {
256
        switch(status) {
257
                case janus_sip_call_status_idle:
258
                        return "idle";
259
                case janus_sip_call_status_inviting:
260
                        return "inviting";
261
                case janus_sip_call_status_invited:
262
                        return "invited";
263
                case janus_sip_call_status_incall:
264
                        return "incall";
265
                case janus_sip_call_status_closing:
266
                        return "closing";
267
                default:
268
                        return "unknown";
269
        }
270
}
271

    
272

    
273
/* Sofia stuff */
274
typedef struct ssip_s ssip_t;
275
typedef struct ssip_oper_s ssip_oper_t;
276

    
277
typedef enum {
278
        janus_sip_secret_type_plaintext = 1,
279
        janus_sip_secret_type_hashed = 2,
280
        janus_sip_secret_type_unknown
281
} janus_sip_secret_type;
282

    
283
typedef struct janus_sip_account {
284
        char *identity;
285
        char *user_agent;                /* Used to override the general UA string */
286
        gboolean sips;
287
        char *username;
288
        char *display_name;                /* Used for outgoing calls in the From header */
289
        char *authuser;                        /**< username to use for authentication */
290
        char *secret;
291
        janus_sip_secret_type secret_type;
292
        int sip_port;
293
        char *proxy;
294
        janus_sip_registration_status registration_status;
295
} janus_sip_account;
296

    
297
typedef struct janus_sip_media {
298
        char *remote_ip;
299
        int ready:1;
300
        gboolean autoack;
301
        gboolean require_srtp, has_srtp_local, has_srtp_remote;
302
        int has_audio:1;
303
        int audio_rtp_fd, audio_rtcp_fd;
304
        int local_audio_rtp_port, remote_audio_rtp_port;
305
        int local_audio_rtcp_port, remote_audio_rtcp_port;
306
        guint32 audio_ssrc, audio_ssrc_peer;
307
        int audio_pt;
308
        const char *audio_pt_name;
309
        srtp_t audio_srtp_in, audio_srtp_out;
310
        srtp_policy_t audio_remote_policy, audio_local_policy;
311
        int audio_srtp_suite_in, audio_srtp_suite_out;
312
        int has_video:1;
313
        int video_rtp_fd, video_rtcp_fd;
314
        int local_video_rtp_port, remote_video_rtp_port;
315
        int local_video_rtcp_port, remote_video_rtcp_port;
316
        guint32 video_ssrc, video_ssrc_peer;
317
        int video_pt;
318
        const char *video_pt_name;
319
        srtp_t video_srtp_in, video_srtp_out;
320
        srtp_policy_t video_remote_policy, video_local_policy;
321
        int video_srtp_suite_in, video_srtp_suite_out;
322
} janus_sip_media;
323

    
324
typedef struct janus_sip_session {
325
        janus_plugin_session *handle;
326
        ssip_t *stack;
327
        janus_sip_account account;
328
        janus_sip_call_status status;
329
        janus_sip_media media;
330
        sdp_parser_t *raw_media;
331
        char *transaction;
332
        char *callee;
333
        janus_recorder *arc;                /* The Janus recorder instance for this user's audio, if enabled */
334
        janus_recorder *arc_peer;        /* The Janus recorder instance for the peer's audio, if enabled */
335
        janus_recorder *vrc;                /* The Janus recorder instance for this user's video, if enabled */
336
        janus_recorder *vrc_peer;        /* The Janus recorder instance for the peer's video, if enabled */
337
        janus_mutex rec_mutex;                /* Mutex to protect the recorders from race conditions */
338
        volatile gint hangingup;
339
        gint64 destroyed;        /* Time at which this session was marked as destroyed */
340
        janus_mutex mutex;
341
} janus_sip_session;
342
static GHashTable *sessions;
343
static GList *old_sessions;
344
static janus_mutex sessions_mutex;
345

    
346

    
347
#undef SU_ROOT_MAGIC_T
348
#define SU_ROOT_MAGIC_T        ssip_t
349
#undef NUA_MAGIC_T
350
#define NUA_MAGIC_T                ssip_t
351
#undef NUA_HMAGIC_T
352
#define NUA_HMAGIC_T        ssip_oper_t
353

    
354
struct ssip_s {
355
        su_home_t s_home[1];
356
        su_root_t *s_root;
357
        nua_t *s_nua;
358
        nua_handle_t *s_nh_r, *s_nh_i;
359
        janus_sip_session *session;
360
};
361

    
362

    
363
/* SRTP stuff (in case we need SDES) */
364
#define SRTP_MASTER_KEY_LENGTH        16
365
#define SRTP_MASTER_SALT_LENGTH        14
366
#define SRTP_MASTER_LENGTH (SRTP_MASTER_KEY_LENGTH + SRTP_MASTER_SALT_LENGTH)
367
static const char *janus_sip_srtp_error[] =
368
{
369
        "err_status_ok",
370
        "err_status_fail",
371
        "err_status_bad_param",
372
        "err_status_alloc_fail",
373
        "err_status_dealloc_fail",
374
        "err_status_init_fail",
375
        "err_status_terminus",
376
        "err_status_auth_fail",
377
        "err_status_cipher_fail",
378
        "err_status_replay_fail",
379
        "err_status_replay_old",
380
        "err_status_algo_fail",
381
        "err_status_no_such_op",
382
        "err_status_no_ctx",
383
        "err_status_cant_check",
384
        "err_status_key_expired",
385
        "err_status_socket_err",
386
        "err_status_signal_err",
387
        "err_status_nonce_bad",
388
        "err_status_read_fail",
389
        "err_status_write_fail",
390
        "err_status_parse_err",
391
        "err_status_encode_err",
392
        "err_status_semaphore_err",
393
        "err_status_pfkey_err",
394
};
395
static const gchar *janus_sip_get_srtp_error(int error) {
396
        if(error < 0 || error > 24)
397
                return NULL;
398
        return janus_sip_srtp_error[error];
399
}
400
static int janus_sip_srtp_set_local(janus_sip_session *session, gboolean video, char **crypto) {
401
        if(session == NULL)
402
                return -1;
403
        /* Generate key/salt */
404
        uint8_t *key = g_malloc0(SRTP_MASTER_LENGTH);
405
        crypto_get_random(key, SRTP_MASTER_LENGTH);
406
        /* Set SRTP policies */
407
        srtp_policy_t *policy = video ? &session->media.video_local_policy : &session->media.audio_local_policy;
408
        crypto_policy_set_rtp_default(&(policy->rtp));
409
        crypto_policy_set_rtcp_default(&(policy->rtcp));
410
        policy->ssrc.type = ssrc_any_inbound;
411
        policy->key = key;
412
        policy->next = NULL;
413
        /* Create SRTP context */
414
        err_status_t res = srtp_create(video ? &session->media.video_srtp_out : &session->media.audio_srtp_out, policy);
415
        if(res != err_status_ok) {
416
                /* Something went wrong... */
417
                JANUS_LOG(LOG_ERR, "Oops, error creating outbound SRTP session: %d (%s)\n", res, janus_sip_get_srtp_error(res));
418
                g_free(key);
419
                policy->key = NULL;
420
                return -2;
421
        }
422
        /* Base64 encode the salt */
423
        *crypto = g_base64_encode(key, SRTP_MASTER_LENGTH);
424
        if((video && session->media.video_srtp_out) || (!video && session->media.audio_srtp_out)) {
425
                JANUS_LOG(LOG_VERB, "%s outbound SRTP session created\n", video ? "Video" : "Audio");
426
        }
427
        return 0;
428
}
429
static int janus_sip_srtp_set_remote(janus_sip_session *session, gboolean video, const char *crypto, int suite) {
430
        if(session == NULL || crypto == NULL)
431
                return -1;
432
        /* Base64 decode the crypto string and set it as the remote SRTP context */
433
        gsize len = 0;
434
        guchar *decoded = g_base64_decode(crypto, &len);
435
        if(len < SRTP_MASTER_LENGTH) {
436
                /* FIXME Can this happen? */
437
                g_free(decoded);
438
                return -2;
439
        }
440
        /* Set SRTP policies */
441
        srtp_policy_t *policy = video ? &session->media.video_remote_policy : &session->media.audio_remote_policy;
442
        crypto_policy_set_rtp_default(&(policy->rtp));
443
        crypto_policy_set_rtcp_default(&(policy->rtcp));
444
        if(suite == 32) {
445
                crypto_policy_set_aes_cm_128_hmac_sha1_32(&(policy->rtp));
446
                crypto_policy_set_aes_cm_128_hmac_sha1_32(&(policy->rtcp));
447
        } else if(suite == 80) {
448
                crypto_policy_set_aes_cm_128_hmac_sha1_80(&(policy->rtp));
449
                crypto_policy_set_aes_cm_128_hmac_sha1_80(&(policy->rtcp));
450
        }
451
        policy->ssrc.type = ssrc_any_inbound;
452
        policy->key = decoded;
453
        policy->next = NULL;
454
        /* Create SRTP context */
455
        err_status_t res = srtp_create(video ? &session->media.video_srtp_in : &session->media.audio_srtp_in, policy);
456
        if(res != err_status_ok) {
457
                /* Something went wrong... */
458
                JANUS_LOG(LOG_ERR, "Oops, error creating inbound SRTP session: %d (%s)\n", res, janus_sip_get_srtp_error(res));
459
                g_free(decoded);
460
                policy->key = NULL;
461
                return -2;
462
        }
463
        if((video && session->media.video_srtp_in) || (!video && session->media.audio_srtp_in)) {
464
                JANUS_LOG(LOG_VERB, "%s inbound SRTP session created\n", video ? "Video" : "Audio");
465
        }
466
        return 0;
467
}
468
static void janus_sip_srtp_cleanup(janus_sip_session *session) {
469
        if(session == NULL)
470
                return;
471
        session->media.autoack = TRUE;
472
        session->media.require_srtp = FALSE;
473
        session->media.has_srtp_local = FALSE;
474
        session->media.has_srtp_remote = FALSE;
475
        /* Audio */
476
        if(session->media.audio_srtp_out)
477
                srtp_dealloc(session->media.audio_srtp_out);
478
        session->media.audio_srtp_out = NULL;
479
        g_free(session->media.audio_local_policy.key);
480
        session->media.audio_local_policy.key = NULL;
481
        session->media.audio_srtp_suite_out = 0;
482
        if(session->media.audio_srtp_in)
483
                srtp_dealloc(session->media.audio_srtp_in);
484
        session->media.audio_srtp_in = NULL;
485
        g_free(session->media.audio_remote_policy.key);
486
        session->media.audio_remote_policy.key = NULL;
487
        session->media.audio_srtp_suite_in = 0;
488
        /* Video */
489
        if(session->media.video_srtp_out)
490
                srtp_dealloc(session->media.video_srtp_out);
491
        session->media.video_srtp_out = NULL;
492
        g_free(session->media.video_local_policy.key);
493
        session->media.video_local_policy.key = NULL;
494
        session->media.video_srtp_suite_out = 0;
495
        if(session->media.video_srtp_in)
496
                srtp_dealloc(session->media.video_srtp_in);
497
        session->media.video_srtp_in = NULL;
498
        g_free(session->media.video_remote_policy.key);
499
        session->media.video_remote_policy.key = NULL;
500
        session->media.video_srtp_suite_in = 0;
501
}
502

    
503

    
504
/* Sofia Event thread */
505
gpointer janus_sip_sofia_thread(gpointer user_data);
506
/* Sofia callbacks */
507
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[]);
508
/* SDP parsing and manipulation */
509
void janus_sip_sdp_process(janus_sip_session *session, sdp_session_t *sdp, gboolean answer);
510
char *janus_sip_sdp_manipulate(janus_sip_session *session, sdp_session_t *sdp, gboolean answer);
511
/* Media */
512
static int janus_sip_allocate_local_ports(janus_sip_session *session);
513
static void *janus_sip_relay_thread(void *data);
514

    
515

    
516
/* URI parsing utilies */
517

    
518
#define JANUS_SIP_URI_MAXLEN        1024
519
typedef struct {
520
        char data[JANUS_SIP_URI_MAXLEN];
521
        url_t url[1];
522
} janus_sip_uri_t;
523

    
524
/* Parses a SIP URI (SIPS is not supported), returns 0 on success, -1 otherwise */
525
static int janus_sip_parse_uri(janus_sip_uri_t *sip_uri, const char *data) {
526
        g_strlcpy(sip_uri->data, data, JANUS_SIP_URI_MAXLEN);
527
        if (url_d(sip_uri->url, sip_uri->data) < 0 || sip_uri->url->url_type != url_sip)
528
                return -1;
529
        return 0;
530
}
531

    
532
/* Similar to the above function, but it also accepts SIPS URIs */
533
static int janus_sip_parse_proxy_uri(janus_sip_uri_t *sip_uri, const char *data) {
534
        g_strlcpy(sip_uri->data, data, JANUS_SIP_URI_MAXLEN);
535
        if (url_d(sip_uri->url, sip_uri->data) < 0 || (sip_uri->url->url_type != url_sip && sip_uri->url->url_type != url_sips))
536
                return -1;
537
        return 0;
538
}
539

    
540
/* Error codes */
541
#define JANUS_SIP_ERROR_UNKNOWN_ERROR                499
542
#define JANUS_SIP_ERROR_NO_MESSAGE                        440
543
#define JANUS_SIP_ERROR_INVALID_JSON                441
544
#define JANUS_SIP_ERROR_INVALID_REQUEST                442
545
#define JANUS_SIP_ERROR_MISSING_ELEMENT                443
546
#define JANUS_SIP_ERROR_INVALID_ELEMENT                444
547
#define JANUS_SIP_ERROR_ALREADY_REGISTERED        445
548
#define JANUS_SIP_ERROR_INVALID_ADDRESS                446
549
#define JANUS_SIP_ERROR_WRONG_STATE                        447
550
#define JANUS_SIP_ERROR_MISSING_SDP                        448
551
#define JANUS_SIP_ERROR_LIBSOFIA_ERROR                449
552
#define JANUS_SIP_ERROR_IO_ERROR                        450
553
#define JANUS_SIP_ERROR_RECORDING_ERROR                451
554
#define JANUS_SIP_ERROR_TOO_STRICT                        452
555

    
556

    
557
/* SIP watchdog/garbage collector (sort of) */
558
void *janus_sip_watchdog(void *data);
559
void *janus_sip_watchdog(void *data) {
560
        JANUS_LOG(LOG_INFO, "SIP watchdog started\n");
561
        gint64 now = 0;
562
        while(g_atomic_int_get(&initialized) && !g_atomic_int_get(&stopping)) {
563
                janus_mutex_lock(&sessions_mutex);
564
                /* Iterate on all the sessions */
565
                now = janus_get_monotonic_time();
566
                if(old_sessions != NULL) {
567
                        GList *sl = old_sessions;
568
                        JANUS_LOG(LOG_HUGE, "Checking %d old SIP sessions...\n", g_list_length(old_sessions));
569
                        while(sl) {
570
                                janus_sip_session *session = (janus_sip_session *)sl->data;
571
                                if(!session) {
572
                                        sl = sl->next;
573
                                        continue;
574
                                }
575
                                if (now-session->destroyed >= 5*G_USEC_PER_SEC) {
576
                                        /* We're lazy and actually get rid of the stuff only after a few seconds */
577
                                        JANUS_LOG(LOG_VERB, "Freeing old SIP session\n");
578
                                        GList *rm = sl->next;
579
                                        old_sessions = g_list_delete_link(old_sessions, sl);
580
                                        sl = rm;
581
                                        if (session->account.identity) {
582
                                            g_free(session->account.identity);
583
                                            session->account.identity = NULL;
584
                                        }
585
                                        session->account.sips = TRUE;
586
                                        if (session->account.proxy) {
587
                                            g_free(session->account.proxy);
588
                                            session->account.proxy = NULL;
589
                                        }
590
                                        if (session->account.secret) {
591
                                            g_free(session->account.secret);
592
                                            session->account.secret = NULL;
593
                                        }
594
                                        if (session->account.username) {
595
                                            g_free(session->account.username);
596
                                            session->account.username = NULL;
597
                                        }
598
                                        if (session->account.display_name) {
599
                                            g_free(session->account.display_name);
600
                                            session->account.display_name = NULL;
601
                                        }
602
                                        if (session->account.user_agent) {
603
                                            g_free(session->account.user_agent);
604
                                            session->account.user_agent = NULL;
605
                                        }
606
                                        if (session->account.authuser) {
607
                                            g_free(session->account.authuser);
608
                                            session->account.authuser = NULL;
609
                                        }
610
                                        if (session->callee) {
611
                                            g_free(session->callee);
612
                                            session->callee = NULL;
613
                                        }
614
                                        if (session->transaction) {
615
                                            g_free(session->transaction);
616
                                            session->transaction = NULL;
617
                                        }
618
                                        if (session->media.remote_ip) {
619
                                            g_free(session->media.remote_ip);
620
                                            session->media.remote_ip = NULL;
621
                                        }
622
                                        janus_sip_srtp_cleanup(session);
623
                                        session->handle = NULL;
624
                                        g_free(session);
625
                                        session = NULL;
626
                                        continue;
627
                                }
628
                                sl = sl->next;
629
                        }
630
                }
631
                janus_mutex_unlock(&sessions_mutex);
632
                g_usleep(500000);
633
        }
634
        JANUS_LOG(LOG_INFO, "SIP watchdog stopped\n");
635
        return NULL;
636
}
637

    
638

    
639
static void janus_sip_detect_local_ip(char *buf, size_t buflen) {
640
        JANUS_LOG(LOG_VERB, "Autodetecting local IP...\n");
641

    
642
        struct sockaddr_in addr;
643
        socklen_t len;
644
        int fd = socket(AF_INET, SOCK_DGRAM, 0);
645
        if (fd == -1)
646
                goto error;
647
        addr.sin_family = AF_INET;
648
        addr.sin_port = htons(1);
649
        inet_pton(AF_INET, "1.2.3.4", &addr.sin_addr.s_addr);
650
        if (connect(fd, (const struct sockaddr*) &addr, sizeof(addr)) < 0)
651
                goto error;
652
        len = sizeof(addr);
653
        if (getsockname(fd, (struct sockaddr*) &addr, &len) < 0)
654
                goto error;
655
        if (getnameinfo((const struct sockaddr*) &addr, sizeof(addr),
656
                        buf, buflen,
657
                        NULL, 0, NI_NUMERICHOST) != 0)
658
                goto error;
659
        close(fd);
660
        return;
661

    
662
error:
663
        if (fd != -1)
664
                close(fd);
665
        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");
666
        g_strlcpy(buf, "127.0.0.1", buflen);
667
}
668

    
669

    
670
/* Plugin implementation */
671
int janus_sip_init(janus_callbacks *callback, const char *config_path) {
672
        if(g_atomic_int_get(&stopping)) {
673
                /* Still stopping from before */
674
                return -1;
675
        }
676
        if(callback == NULL || config_path == NULL) {
677
                /* Invalid arguments */
678
                return -1;
679
        }
680

    
681
        /* Read configuration */
682
        char filename[255];
683
        g_snprintf(filename, 255, "%s/%s.cfg", config_path, JANUS_SIP_PACKAGE);
684
        JANUS_LOG(LOG_VERB, "Configuration file: %s\n", filename);
685
        janus_config *config = janus_config_parse(filename);
686
        if(config != NULL)
687
                janus_config_print(config);
688

    
689
        gboolean local_ip_set = FALSE;
690
        janus_config_item *item = janus_config_get_item_drilldown(config, "general", "local_ip");
691
        if(item && item->value) {
692
                int family;
693
                if (!janus_is_ip_valid(item->value, &family)) {
694
                        JANUS_LOG(LOG_WARN, "Invalid local IP specified: %s, guessing the default...\n", item->value);
695
                } else {
696
                        /* Verify that we can actually bind to that address */
697
                        int fd = socket(family, SOCK_DGRAM, 0);
698
                        if (fd == -1) {
699
                                JANUS_LOG(LOG_WARN, "Error creating test socket, falling back to detecting IP address...\n");
700
                        } else {
701
                                int r;
702
                                struct sockaddr_storage ss;
703
                                socklen_t addrlen;
704
                                memset(&ss, 0, sizeof(ss));
705
                                if (family == AF_INET) {
706
                                        struct sockaddr_in *addr4 = (struct sockaddr_in*)&ss;
707
                                        addr4->sin_family = AF_INET;
708
                                        addr4->sin_port = 0;
709
                                        inet_pton(AF_INET, item->value, &(addr4->sin_addr.s_addr));
710
                                        addrlen = sizeof(struct sockaddr_in);
711
                                } else {
712
                                        struct sockaddr_in6 *addr6 = (struct sockaddr_in6*)&ss;
713
                                        addr6->sin6_family = AF_INET6;
714
                                        addr6->sin6_port = 0;
715
                                        inet_pton(AF_INET6, item->value, &(addr6->sin6_addr.s6_addr));
716
                                        addrlen = sizeof(struct sockaddr_in6);
717
                                }
718
                                r = bind(fd, (const struct sockaddr*)&ss, addrlen);
719
                                close(fd);
720
                                if (r < 0) {
721
                                        JANUS_LOG(LOG_WARN, "Error setting local IP address to %s, falling back to detecting IP address...\n", item->value);
722
                                } else {
723
                                        g_strlcpy(local_ip, item->value, sizeof(local_ip));
724
                                        local_ip_set = TRUE;
725
                                }
726
                        }
727
                }
728
        }
729
        if (!local_ip_set)
730
                janus_sip_detect_local_ip(local_ip, sizeof(local_ip));
731
        JANUS_LOG(LOG_VERB, "Local IP set to %s\n", local_ip);
732

    
733
        item = janus_config_get_item_drilldown(config, "general", "keepalive_interval");
734
        if(item && item->value)
735
                keepalive_interval = atoi(item->value);
736
        JANUS_LOG(LOG_VERB, "SIP keep-alive interval set to %d seconds\n", keepalive_interval);
737

    
738
        item = janus_config_get_item_drilldown(config, "general", "register_ttl");
739
        if(item && item->value)
740
                register_ttl = atoi(item->value);
741
        JANUS_LOG(LOG_VERB, "SIP registration TTL set to %d seconds\n", register_ttl);
742

    
743
        item = janus_config_get_item_drilldown(config, "general", "behind_nat");
744
        if(item && item->value)
745
                behind_nat = janus_is_true(item->value);
746

    
747
        item = janus_config_get_item_drilldown(config, "general", "user_agent");
748
        if(item && item->value)
749
                user_agent = g_strdup(item->value);
750
        else
751
                user_agent = g_strdup("Janus WebRTC Gateway SIP Plugin "JANUS_SIP_VERSION_STRING);
752
        JANUS_LOG(LOG_VERB, "SIP User-Agent set to %s\n", user_agent);
753

    
754
        /* This plugin actually has nothing to configure... */
755
        janus_config_destroy(config);
756
        config = NULL;
757

    
758
        /* Setup sofia */
759
        su_init();
760

    
761
        sessions = g_hash_table_new(NULL, NULL);
762
        janus_mutex_init(&sessions_mutex);
763
        messages = g_async_queue_new_full((GDestroyNotify) janus_sip_message_free);
764
        /* This is the callback we'll need to invoke to contact the gateway */
765
        gateway = callback;
766

    
767
        g_atomic_int_set(&initialized, 1);
768

    
769
        GError *error = NULL;
770
        /* Start the sessions watchdog */
771
        watchdog = g_thread_try_new("etest watchdog", &janus_sip_watchdog, NULL, &error);
772
        if(error != NULL) {
773
                g_atomic_int_set(&initialized, 0);
774
                JANUS_LOG(LOG_ERR, "Got error %d (%s) trying to launch the SIP watchdog thread...\n", error->code, error->message ? error->message : "??");
775
                return -1;
776
        }
777
        /* Launch the thread that will handle incoming messages */
778
        handler_thread = g_thread_try_new("janus sip handler", janus_sip_handler, NULL, &error);
779
        if(error != NULL) {
780
                g_atomic_int_set(&initialized, 0);
781
                JANUS_LOG(LOG_ERR, "Got error %d (%s) trying to launch the SIP handler thread...\n", error->code, error->message ? error->message : "??");
782
                return -1;
783
        }
784
        JANUS_LOG(LOG_INFO, "%s initialized!\n", JANUS_SIP_NAME);
785
        return 0;
786
}
787

    
788
void janus_sip_destroy(void) {
789
        if(!g_atomic_int_get(&initialized))
790
                return;
791
        g_atomic_int_set(&stopping, 1);
792

    
793
        g_async_queue_push(messages, &exit_message);
794
        if(handler_thread != NULL) {
795
                g_thread_join(handler_thread);
796
                handler_thread = NULL;
797
        }
798
        if(watchdog != NULL) {
799
                g_thread_join(watchdog);
800
                watchdog = NULL;
801
        }
802
        /* FIXME We should destroy the sessions cleanly */
803
        janus_mutex_lock(&sessions_mutex);
804
        g_hash_table_destroy(sessions);
805
        janus_mutex_unlock(&sessions_mutex);
806
        g_async_queue_unref(messages);
807
        messages = NULL;
808
        sessions = NULL;
809
        g_atomic_int_set(&initialized, 0);
810
        g_atomic_int_set(&stopping, 0);
811
        JANUS_LOG(LOG_INFO, "%s destroyed!\n", JANUS_SIP_NAME);
812
}
813

    
814
int janus_sip_get_api_compatibility(void) {
815
        /* Important! This is what your plugin MUST always return: don't lie here or bad things will happen */
816
        return JANUS_PLUGIN_API_VERSION;
817
}
818

    
819
int janus_sip_get_version(void) {
820
        return JANUS_SIP_VERSION;
821
}
822

    
823
const char *janus_sip_get_version_string(void) {
824
        return JANUS_SIP_VERSION_STRING;
825
}
826

    
827
const char *janus_sip_get_description(void) {
828
        return JANUS_SIP_DESCRIPTION;
829
}
830

    
831
const char *janus_sip_get_name(void) {
832
        return JANUS_SIP_NAME;
833
}
834

    
835
const char *janus_sip_get_author(void) {
836
        return JANUS_SIP_AUTHOR;
837
}
838

    
839
const char *janus_sip_get_package(void) {
840
        return JANUS_SIP_PACKAGE;
841
}
842

    
843
void janus_sip_create_session(janus_plugin_session *handle, int *error) {
844
        if(g_atomic_int_get(&stopping) || !g_atomic_int_get(&initialized)) {
845
                *error = -1;
846
                return;
847
        }
848
        janus_sip_session *session = g_malloc0(sizeof(janus_sip_session));
849
        session->handle = handle;
850
        session->account.identity = NULL;
851
        session->account.sips = TRUE;
852
        session->account.username = NULL;
853
        session->account.display_name = NULL;
854
        session->account.user_agent = NULL;
855
        session->account.authuser = NULL;
856
        session->account.secret = NULL;
857
        session->account.secret_type = janus_sip_secret_type_unknown;
858
        session->account.sip_port = 0;
859
        session->account.proxy = NULL;
860
        session->account.registration_status = janus_sip_registration_status_unregistered;
861
        session->status = janus_sip_call_status_idle;
862
        session->stack = NULL;
863
        session->transaction = NULL;
864
        session->callee = NULL;
865
        session->media.remote_ip = NULL;
866
        session->media.ready = 0;
867
        session->media.autoack = TRUE;
868
        session->media.require_srtp = FALSE;
869
        session->media.has_srtp_local = FALSE;
870
        session->media.has_srtp_remote = FALSE;
871
        session->media.has_audio = 0;
872
        session->media.audio_rtp_fd = -1;
873
        session->media.audio_rtcp_fd= -1;
874
        session->media.local_audio_rtp_port = 0;
875
        session->media.remote_audio_rtp_port = 0;
876
        session->media.local_audio_rtcp_port = 0;
877
        session->media.remote_audio_rtcp_port = 0;
878
        session->media.audio_ssrc = 0;
879
        session->media.audio_ssrc_peer = 0;
880
        session->media.audio_pt = -1;
881
        session->media.audio_pt_name = NULL;
882
        session->media.audio_srtp_suite_in = 0;
883
        session->media.audio_srtp_suite_out = 0;
884
        session->media.has_video = 0;
885
        session->media.video_rtp_fd = -1;
886
        session->media.video_rtcp_fd= -1;
887
        session->media.local_video_rtp_port = 0;
888
        session->media.remote_video_rtp_port = 0;
889
        session->media.local_video_rtcp_port = 0;
890
        session->media.remote_video_rtcp_port = 0;
891
        session->media.video_ssrc = 0;
892
        session->media.video_ssrc_peer = 0;
893
        session->media.video_pt = -1;
894
        session->media.video_pt_name = NULL;
895
        session->media.video_srtp_suite_in = 0;
896
        session->media.video_srtp_suite_out = 0;
897
        session->raw_media = NULL;
898
        janus_mutex_init(&session->rec_mutex);
899
        session->destroyed = 0;
900
        g_atomic_int_set(&session->hangingup, 0);
901
        janus_mutex_init(&session->mutex);
902
        handle->plugin_handle = session;
903

    
904
        janus_mutex_lock(&sessions_mutex);
905
        g_hash_table_insert(sessions, handle, session);
906
        janus_mutex_unlock(&sessions_mutex);
907

    
908
        return;
909
}
910

    
911
void janus_sip_destroy_session(janus_plugin_session *handle, int *error) {
912
        if(g_atomic_int_get(&stopping) || !g_atomic_int_get(&initialized)) {
913
                *error = -1;
914
                return;
915
        }
916
        janus_sip_session *session = (janus_sip_session *)handle->plugin_handle;
917
        if(!session) {
918
                JANUS_LOG(LOG_ERR, "No SIP session associated with this handle...\n");
919
                *error = -2;
920
                return;
921
        }
922
        janus_mutex_lock(&sessions_mutex);
923
        if(!session->destroyed) {
924
                g_hash_table_remove(sessions, handle);
925
                janus_sip_hangup_media(handle);
926
                session->destroyed = janus_get_monotonic_time();
927
                JANUS_LOG(LOG_VERB, "Destroying SIP session (%s)...\n", session->account.username ? session->account.username : "unregistered user");
928
                if(session->stack != NULL) {
929
                        /* Shutdown the NUA: this will remove the session later on */
930
                        nua_shutdown(session->stack->s_nua);
931
                } else {
932
                        /* No stack, maybe never registered: cleaning up and removing the session is done in a lazy way */
933
                        old_sessions = g_list_append(old_sessions, session);
934
                }
935
        }
936
        janus_mutex_unlock(&sessions_mutex);
937
        return;
938
}
939

    
940
char *janus_sip_query_session(janus_plugin_session *handle) {
941
        if(g_atomic_int_get(&stopping) || !g_atomic_int_get(&initialized)) {
942
                return NULL;
943
        }
944
        janus_sip_session *session = (janus_sip_session *)handle->plugin_handle;
945
        if(!session) {
946
                JANUS_LOG(LOG_ERR, "No session associated with this handle...\n");
947
                return NULL;
948
        }
949
        /* Provide some generic info, e.g., if we're in a call and with whom */
950
        json_t *info = json_object();
951
        json_object_set_new(info, "username", session->account.username ? json_string(session->account.username) : NULL);
952
        json_object_set_new(info, "display_name", session->account.display_name ? json_string(session->account.display_name) : NULL);
953
        json_object_set_new(info, "user_agent", session->account.user_agent ? json_string(session->account.user_agent) : NULL);
954
        json_object_set_new(info, "identity", session->account.identity ? json_string(session->account.identity) : NULL);
955
        json_object_set_new(info, "registration_status", json_string(janus_sip_registration_status_string(session->account.registration_status)));
956
        json_object_set_new(info, "call_status", json_string(janus_sip_call_status_string(session->status)));
957
        if(session->callee) {
958
                json_object_set_new(info, "callee", json_string(session->callee ? session->callee : "??"));
959
                json_object_set_new(info, "auto-ack", json_string(session->media.autoack ? "yes" : "no"));
960
                json_object_set_new(info, "srtp-required", json_string(session->media.require_srtp ? "yes" : "no"));
961
                json_object_set_new(info, "sdes-local", json_string(session->media.has_srtp_local ? "yes" : "no"));
962
                json_object_set_new(info, "sdes-remote", json_string(session->media.has_srtp_remote ? "yes" : "no"));
963
        }
964
        if(session->arc || session->vrc || session->arc_peer || session->vrc_peer) {
965
                json_t *recording = json_object();
966
                if(session->arc && session->arc->filename)
967
                        json_object_set_new(recording, "audio", json_string(session->arc->filename));
968
                if(session->vrc && session->vrc->filename)
969
                        json_object_set_new(recording, "video", json_string(session->vrc->filename));
970
                if(session->arc_peer && session->arc_peer->filename)
971
                        json_object_set_new(recording, "audio-peer", json_string(session->arc_peer->filename));
972
                if(session->vrc_peer && session->vrc_peer->filename)
973
                        json_object_set_new(recording, "video-peer", json_string(session->vrc_peer->filename));
974
                json_object_set_new(info, "recording", recording);
975
        }
976
        json_object_set_new(info, "destroyed", json_integer(session->destroyed));
977
        char *info_text = json_dumps(info, JSON_INDENT(3) | JSON_PRESERVE_ORDER);
978
        json_decref(info);
979
        return info_text;
980
}
981

    
982
struct janus_plugin_result *janus_sip_handle_message(janus_plugin_session *handle, char *transaction, char *message, char *sdp_type, char *sdp) {
983
        if(g_atomic_int_get(&stopping) || !g_atomic_int_get(&initialized))
984
                return janus_plugin_result_new(JANUS_PLUGIN_ERROR, g_atomic_int_get(&stopping) ? "Shutting down" : "Plugin not initialized");
985
        JANUS_LOG(LOG_VERB, "%s\n", message);
986
        janus_sip_message *msg = g_malloc0(sizeof(janus_sip_message));
987
        msg->handle = handle;
988
        msg->transaction = transaction;
989
        msg->message = message;
990
        msg->sdp_type = sdp_type;
991
        msg->sdp = sdp;
992
        g_async_queue_push(messages, msg);
993

    
994
        /* All the requests to this plugin are handled asynchronously */
995
        return janus_plugin_result_new(JANUS_PLUGIN_OK_WAIT, NULL);
996
}
997

    
998
void janus_sip_setup_media(janus_plugin_session *handle) {
999
        JANUS_LOG(LOG_INFO, "WebRTC media is now available\n");
1000
        if(g_atomic_int_get(&stopping) || !g_atomic_int_get(&initialized))
1001
                return;
1002
        janus_sip_session *session = (janus_sip_session *)handle->plugin_handle;
1003
        if(!session) {
1004
                JANUS_LOG(LOG_ERR, "No session associated with this handle...\n");
1005
                return;
1006
        }
1007
        if(session->destroyed)
1008
                return;
1009
        g_atomic_int_set(&session->hangingup, 0);
1010
        /* TODO Only relay RTP/RTCP when we get this event */
1011
}
1012

    
1013
void janus_sip_incoming_rtp(janus_plugin_session *handle, int video, char *buf, int len) {
1014
        if(handle == NULL || handle->stopped || g_atomic_int_get(&stopping) || !g_atomic_int_get(&initialized))
1015
                return;
1016
        if(gateway) {
1017
                /* Honour the audio/video active flags */
1018
                janus_sip_session *session = (janus_sip_session *)handle->plugin_handle;
1019
                if(!session || session->destroyed) {
1020
                        JANUS_LOG(LOG_ERR, "No session associated with this handle...\n");
1021
                        return;
1022
                }
1023
                if(session->status != janus_sip_call_status_incall)
1024
                        return;
1025
                /* Forward to our SIP peer */
1026
                if(video) {
1027
                        if(session->media.video_ssrc == 0) {
1028
                                rtp_header *header = (rtp_header *)buf;
1029
                                session->media.video_ssrc = ntohl(header->ssrc);
1030
                                JANUS_LOG(LOG_VERB, "Got SIP video SSRC: %"SCNu32"\n", session->media.video_ssrc);
1031
                        }
1032
                        if(session->media.has_video && session->media.video_rtp_fd) {
1033
                                /* Save the frame if we're recording */
1034
                                janus_recorder_save_frame(session->vrc, buf, len);
1035
                                /* Is SRTP involved? */
1036
                                if(session->media.has_srtp_local) {
1037
                                        char sbuf[2048];
1038
                                        memcpy(&sbuf, buf, len);
1039
                                        int protected = len;
1040
                                        int res = srtp_protect(session->media.video_srtp_out, &sbuf, &protected);
1041
                                        if(res != err_status_ok) {
1042
                                                rtp_header *header = (rtp_header *)&sbuf;
1043
                                                guint32 timestamp = ntohl(header->timestamp);
1044
                                                guint16 seq = ntohs(header->seq_number);
1045
                                                JANUS_LOG(LOG_ERR, "[SIP-%s] Video SRTP protect error... %s (len=%d-->%d, ts=%"SCNu32", seq=%"SCNu16")...\n",
1046
                                                        session->account.username, janus_sip_get_srtp_error(res), len, protected, timestamp, seq);
1047
                                        } else {
1048
                                                /* Forward the frame to the peer */
1049
                                                send(session->media.video_rtp_fd, sbuf, protected, 0);
1050
                                        }
1051
                                } else {
1052
                                        /* Forward the frame to the peer */
1053
                                        send(session->media.video_rtp_fd, buf, len, 0);
1054
                                }
1055
                        }
1056
                } else {
1057
                        if(session->media.audio_ssrc == 0) {
1058
                                rtp_header *header = (rtp_header *)buf;
1059
                                session->media.audio_ssrc = ntohl(header->ssrc);
1060
                                JANUS_LOG(LOG_VERB, "Got SIP audio SSRC: %"SCNu32"\n", session->media.audio_ssrc);
1061
                        }
1062
                        if(session->media.has_audio && session->media.audio_rtp_fd) {
1063
                                /* Save the frame if we're recording */
1064
                                janus_recorder_save_frame(session->arc, buf, len);
1065
                                /* Is SRTP involved? */
1066
                                if(session->media.has_srtp_local) {
1067
                                        char sbuf[2048];
1068
                                        memcpy(&sbuf, buf, len);
1069
                                        int protected = len;
1070
                                        int res = srtp_protect(session->media.audio_srtp_out, &sbuf, &protected);
1071
                                        if(res != err_status_ok) {
1072
                                                rtp_header *header = (rtp_header *)&sbuf;
1073
                                                guint32 timestamp = ntohl(header->timestamp);
1074
                                                guint16 seq = ntohs(header->seq_number);
1075
                                                JANUS_LOG(LOG_ERR, "[SIP-%s] Audio SRTP protect error... %s (len=%d-->%d, ts=%"SCNu32", seq=%"SCNu16")...\n",
1076
                                                        session->account.username, janus_sip_get_srtp_error(res), len, protected, timestamp, seq);
1077
                                        } else {
1078
                                                /* Forward the frame to the peer */
1079
                                                send(session->media.audio_rtp_fd, sbuf, protected, 0);
1080
                                        }
1081
                                } else {
1082
                                        /* Forward the frame to the peer */
1083
                                        send(session->media.audio_rtp_fd, buf, len, 0);
1084
                                }
1085
                        }
1086
                }
1087
        }
1088
}
1089

    
1090
void janus_sip_incoming_rtcp(janus_plugin_session *handle, int video, char *buf, int len) {
1091
        if(handle == NULL || handle->stopped || g_atomic_int_get(&stopping) || !g_atomic_int_get(&initialized))
1092
                return;
1093
        if(gateway) {
1094
                janus_sip_session *session = (janus_sip_session *)handle->plugin_handle;
1095
                if(!session || session->destroyed) {
1096
                        JANUS_LOG(LOG_ERR, "No session associated with this handle...\n");
1097
                        return;
1098
                }
1099
                if(session->status != janus_sip_call_status_incall)
1100
                        return;
1101
                /* Forward to our SIP peer */
1102
                if(video) {
1103
                        if(session->media.has_video && session->media.video_rtcp_fd) {
1104
                                /* Is SRTP involved? */
1105
                                if(session->media.has_srtp_local) {
1106
                                        char sbuf[2048];
1107
                                        memcpy(&sbuf, buf, len);
1108
                                        int protected = len;
1109
                                        int res = srtp_protect_rtcp(session->media.video_srtp_out, &sbuf, &protected);
1110
                                        if(res != err_status_ok) {
1111
                                                JANUS_LOG(LOG_ERR, "[SIP-%s] Video SRTCP protect error... %s (len=%d-->%d)...\n",
1112
                                                        session->account.username, janus_sip_get_srtp_error(res), len, protected);
1113
                                        } else {
1114
                                                /* Fix SSRCs as the gateway does */
1115
                                                JANUS_LOG(LOG_HUGE, "[SIP] Fixing SSRCs (local %u, peer %u)\n",
1116
                                                        session->media.video_ssrc, session->media.video_ssrc_peer);
1117
                                                janus_rtcp_fix_ssrc(NULL, (char *)buf, len, 1, session->media.video_ssrc, session->media.video_ssrc_peer);
1118
                                                /* Forward the message to the peer */
1119
                                                send(session->media.video_rtcp_fd, sbuf, protected, 0);
1120
                                        }
1121
                                } else {
1122
                                        /* Fix SSRCs as the gateway does */
1123
                                        JANUS_LOG(LOG_HUGE, "[SIP] Fixing SSRCs (local %u, peer %u)\n",
1124
                                                session->media.video_ssrc, session->media.video_ssrc_peer);
1125
                                        janus_rtcp_fix_ssrc(NULL, (char *)buf, len, 1, session->media.video_ssrc, session->media.video_ssrc_peer);
1126
                                        /* Forward the message to the peer */
1127
                                        send(session->media.video_rtcp_fd, buf, len, 0);
1128
                                }
1129
                        }
1130
                } else {
1131
                        if(session->media.has_audio && session->media.audio_rtcp_fd) {
1132
                                /* Is SRTP involved? */
1133
                                if(session->media.has_srtp_local) {
1134
                                        char sbuf[2048];
1135
                                        memcpy(&sbuf, buf, len);
1136
                                        int protected = len;
1137
                                        int res = srtp_protect_rtcp(session->media.audio_srtp_out, &sbuf, &protected);
1138
                                        if(res != err_status_ok) {
1139
                                                JANUS_LOG(LOG_ERR, "[SIP-%s] Audio SRTCP protect error... %s (len=%d-->%d)...\n",
1140
                                                        session->account.username, janus_sip_get_srtp_error(res), len, protected);
1141
                                        } else {
1142
                                                /* Fix SSRCs as the gateway does */
1143
                                                JANUS_LOG(LOG_HUGE, "[SIP] Fixing SSRCs (local %u, peer %u)\n",
1144
                                                        session->media.audio_ssrc, session->media.audio_ssrc_peer);
1145
                                                janus_rtcp_fix_ssrc(NULL, (char *)buf, len, 1, session->media.audio_ssrc, session->media.audio_ssrc_peer);
1146
                                                /* Forward the message to the peer */
1147
                                                send(session->media.audio_rtcp_fd, sbuf, protected, 0);
1148
                                        }
1149
                                } else {
1150
                                        /* Fix SSRCs as the gateway does */
1151
                                        JANUS_LOG(LOG_HUGE, "[SIP] Fixing SSRCs (local %u, peer %u)\n",
1152
                                                session->media.audio_ssrc, session->media.audio_ssrc_peer);
1153
                                        janus_rtcp_fix_ssrc(NULL, (char *)buf, len, 1, session->media.audio_ssrc, session->media.audio_ssrc_peer);
1154
                                        /* Forward the message to the peer */
1155
                                        send(session->media.audio_rtcp_fd, buf, len, 0);
1156
                                }
1157
                        }
1158
                }
1159
        }
1160
}
1161

    
1162
void janus_sip_hangup_media(janus_plugin_session *handle) {
1163
        JANUS_LOG(LOG_INFO, "No WebRTC media anymore\n");
1164
        if(g_atomic_int_get(&stopping) || !g_atomic_int_get(&initialized))
1165
                return;
1166
        janus_sip_session *session = (janus_sip_session *)handle->plugin_handle;
1167
        if(!session) {
1168
                JANUS_LOG(LOG_ERR, "No session associated with this handle...\n");
1169
                return;
1170
        }
1171
        if(session->destroyed)
1172
                return;
1173
        if(g_atomic_int_add(&session->hangingup, 1))
1174
                return;
1175
        if(!(session->status == janus_sip_call_status_inviting ||
1176
                 session->status == janus_sip_call_status_invited ||
1177
                 session->status == janus_sip_call_status_incall))
1178
                return;
1179
        /* Get rid of the recorders, if available */
1180
        janus_mutex_lock(&session->rec_mutex);
1181
        if(session->arc) {
1182
                janus_recorder_close(session->arc);
1183
                JANUS_LOG(LOG_INFO, "Closed user's audio recording %s\n", session->arc->filename ? session->arc->filename : "??");
1184
                janus_recorder_free(session->arc);
1185
        }
1186
        session->arc = NULL;
1187
        if(session->arc_peer) {
1188
                janus_recorder_close(session->arc_peer);
1189
                JANUS_LOG(LOG_INFO, "Closed peer's audio recording %s\n", session->arc_peer->filename ? session->arc_peer->filename : "??");
1190
                janus_recorder_free(session->arc_peer);
1191
        }
1192
        session->arc_peer = NULL;
1193
        if(session->vrc) {
1194
                janus_recorder_close(session->vrc);
1195
                JANUS_LOG(LOG_INFO, "Closed user's video recording %s\n", session->vrc->filename ? session->vrc->filename : "??");
1196
                janus_recorder_free(session->vrc);
1197
        }
1198
        session->vrc = NULL;
1199
        if(session->vrc_peer) {
1200
                janus_recorder_close(session->vrc_peer);
1201
                JANUS_LOG(LOG_INFO, "Closed peer's video recording %s\n", session->vrc_peer->filename ? session->vrc_peer->filename : "??");
1202
                janus_recorder_free(session->vrc_peer);
1203
        }
1204
        session->vrc_peer = NULL;
1205
        janus_mutex_unlock(&session->rec_mutex);
1206
        if (session->raw_media != NULL) {
1207
                sdp_parser_free(session->raw_media);
1208
                session->raw_media = NULL;
1209
        }
1210
        /* FIXME Simulate a "hangup" coming from the browser */
1211
        janus_sip_message *msg = g_malloc0(sizeof(janus_sip_message));
1212
        msg->handle = handle;
1213
        msg->message = g_strdup("{\"request\":\"hangup\"}");
1214
        msg->transaction = NULL;
1215
        msg->sdp_type = NULL;
1216
        msg->sdp = NULL;
1217
        g_async_queue_push(messages, msg);
1218
}
1219

    
1220
/* Thread to handle incoming messages */
1221
static void *janus_sip_handler(void *data) {
1222
        JANUS_LOG(LOG_VERB, "Joining SIP handler thread\n");
1223
        janus_sip_message *msg = NULL;
1224
        int error_code = 0;
1225
        char error_cause[512];
1226
        json_t *root = NULL;
1227
        while(g_atomic_int_get(&initialized) && !g_atomic_int_get(&stopping)) {
1228
                msg = g_async_queue_pop(messages);
1229
                if(msg == NULL)
1230
                        continue;
1231
                if(msg == &exit_message)
1232
                        break;
1233
                if(msg->handle == NULL) {
1234
                        janus_sip_message_free(msg);
1235
                        continue;
1236
                }
1237
                janus_sip_session *session = NULL;
1238
                janus_mutex_lock(&sessions_mutex);
1239
                if(g_hash_table_lookup(sessions, msg->handle) != NULL ) {
1240
                        session = (janus_sip_session *)msg->handle->plugin_handle;
1241
                }
1242
                janus_mutex_unlock(&sessions_mutex);
1243
                if(!session) {
1244
                        JANUS_LOG(LOG_ERR, "No session associated with this handle...\n");
1245
                        janus_sip_message_free(msg);
1246
                        continue;
1247
                }
1248
                if(session->destroyed) {
1249
                        janus_sip_message_free(msg);
1250
                        continue;
1251
                }
1252
                /* Handle request */
1253
                error_code = 0;
1254
                root = NULL;
1255
                JANUS_LOG(LOG_VERB, "Handling message: %s\n", msg->message);
1256
                if(msg->message == NULL) {
1257
                        JANUS_LOG(LOG_ERR, "No message??\n");
1258
                        error_code = JANUS_SIP_ERROR_NO_MESSAGE;
1259
                        g_snprintf(error_cause, 512, "%s", "No message??");
1260
                        goto error;
1261
                }
1262
                json_error_t error;
1263
                root = json_loads(msg->message, 0, &error);
1264
                if(!root) {
1265
                        JANUS_LOG(LOG_ERR, "JSON error: on line %d: %s\n", error.line, error.text);
1266
                        error_code = JANUS_SIP_ERROR_INVALID_JSON;
1267
                        g_snprintf(error_cause, 512, "JSON error: on line %d: %s", error.line, error.text);
1268
                        goto error;
1269
                }
1270
                if(!json_is_object(root)) {
1271
                        JANUS_LOG(LOG_ERR, "JSON error: not an object\n");
1272
                        error_code = JANUS_SIP_ERROR_INVALID_JSON;
1273
                        g_snprintf(error_cause, 512, "JSON error: not an object");
1274
                        goto error;
1275
                }
1276
                JANUS_VALIDATE_JSON_OBJECT(root, request_parameters,
1277
                        error_code, error_cause, TRUE,
1278
                        JANUS_SIP_ERROR_MISSING_ELEMENT, JANUS_SIP_ERROR_INVALID_ELEMENT);
1279
                if(error_code != 0)
1280
                        goto error;
1281
                json_t *request = json_object_get(root, "request");
1282
                const char *request_text = json_string_value(request);
1283
                json_t *result = NULL;
1284
                char *sdp_type = NULL, *sdp = NULL;
1285

    
1286
                if(!strcasecmp(request_text, "register")) {
1287
                        /* Send a REGISTER */
1288
                        if(session->account.registration_status > janus_sip_registration_status_unregistered) {
1289
                                JANUS_LOG(LOG_ERR, "Already registered (%s)\n", session->account.username);
1290
                                error_code = JANUS_SIP_ERROR_ALREADY_REGISTERED;
1291
                                g_snprintf(error_cause, 512, "Already registered (%s)", session->account.username);
1292
                                goto error;
1293
                        }
1294

    
1295
                        /* Cleanup old values */
1296
                        if(session->account.identity != NULL)
1297
                                g_free(session->account.identity);
1298
                        session->account.identity = NULL;
1299
                        session->account.sips = TRUE;
1300
                        if(session->account.username != NULL)
1301
                                g_free(session->account.username);
1302
                        session->account.username = NULL;
1303
                        if(session->account.display_name != NULL)
1304
                                g_free(session->account.display_name);
1305
                        session->account.display_name = NULL;
1306
                        if(session->account.authuser != NULL)
1307
                                g_free(session->account.authuser);
1308
                        session->account.authuser = NULL;
1309
                        if(session->account.secret != NULL)
1310
                                g_free(session->account.secret);
1311
                        session->account.secret = NULL;
1312
                        session->account.secret_type = janus_sip_secret_type_unknown;
1313
                        if(session->account.proxy != NULL)
1314
                                g_free(session->account.proxy);
1315
                        session->account.proxy = NULL;
1316
                        if(session->account.user_agent != NULL)
1317
                                g_free(session->account.user_agent);
1318
                        session->account.user_agent = NULL;
1319
                        session->account.registration_status = janus_sip_registration_status_unregistered;
1320

    
1321
                        gboolean guest = FALSE;
1322
                        JANUS_VALIDATE_JSON_OBJECT(root, register_parameters,
1323
                                error_code, error_cause, TRUE,
1324
                                JANUS_SIP_ERROR_MISSING_ELEMENT, JANUS_SIP_ERROR_INVALID_ELEMENT);
1325
                        if(error_code != 0)
1326
                                goto error;
1327
                        json_t *type = json_object_get(root, "type");
1328
                        if(type != NULL) {
1329
                                const char *type_text = json_string_value(type);
1330
                                if(!strcmp(type_text, "guest")) {
1331
                                        JANUS_LOG(LOG_INFO, "Registering as a guest\n");
1332
                                        guest = TRUE;
1333
                                } else {
1334
                                        JANUS_LOG(LOG_WARN, "Unknown type '%s', ignoring...\n", type_text);
1335
                                }
1336
                        }
1337

    
1338
                        gboolean send_register = TRUE;
1339
                        json_t *do_register = json_object_get(root, "send_register");
1340
                        if(do_register != NULL) {
1341
                                if(guest) {
1342
                                        JANUS_LOG(LOG_ERR, "Conflicting elements: send_register cannot be true if guest is true\n");
1343
                                        error_code = JANUS_SIP_ERROR_INVALID_ELEMENT;
1344
                                        g_snprintf(error_cause, 512, "Conflicting elements: send_register cannot be true if guest is true");
1345
                                        goto error;
1346
                                }
1347
                                send_register = json_is_true(do_register);
1348
                        }
1349

    
1350
                        gboolean sips = TRUE;
1351
                        json_t *do_sips = json_object_get(root, "sips");
1352
                        if(do_sips != NULL) {
1353
                                sips = json_is_true(do_sips);
1354
                        }
1355

    
1356
                        /* Parse address */
1357
                        json_t *proxy = json_object_get(root, "proxy");
1358
                        const char *proxy_text = NULL;
1359

    
1360
                        if (proxy && !json_is_null(proxy)) {
1361
                                /* Has to be validated separately because it could be null */
1362
                                JANUS_VALIDATE_JSON_OBJECT(root, proxy_parameters,
1363
                                        error_code, error_cause, TRUE,
1364
                                        JANUS_SIP_ERROR_MISSING_ELEMENT, JANUS_SIP_ERROR_INVALID_ELEMENT);
1365
                                if(error_code != 0)
1366
                                        goto error;
1367
                                proxy_text = json_string_value(proxy);
1368
                                janus_sip_uri_t proxy_uri;
1369
                                if (janus_sip_parse_proxy_uri(&proxy_uri, proxy_text) < 0) {
1370
                                        JANUS_LOG(LOG_ERR, "Invalid proxy address %s\n", proxy_text);
1371
                                        error_code = JANUS_SIP_ERROR_INVALID_ADDRESS;
1372
                                        g_snprintf(error_cause, 512, "Invalid proxy address %s\n", proxy_text);
1373
                                        goto error;
1374
                                }
1375
                        }
1376

    
1377
                        /* Parse register TTL */
1378
                        int ttl = register_ttl;
1379
                        json_t *reg_ttl = json_object_get(root, "register_ttl");
1380
                        if (reg_ttl && json_is_integer(reg_ttl))
1381
                                ttl = json_integer_value(reg_ttl);
1382
                        if (ttl <= 0)
1383
                                ttl = JANUS_DEFAULT_REGISTER_TTL;
1384

    
1385
                        /* Parse display name */
1386
                        const char* display_name_text = NULL;
1387
                        json_t *display_name = json_object_get(root, "display_name");
1388
                        if (display_name && json_is_string(display_name))
1389
                                display_name_text = json_string_value(display_name);
1390

    
1391
                        /* Parse user agent */
1392
                        const char* user_agent_text = NULL;
1393
                        json_t *user_agent = json_object_get(root, "user_agent");
1394
                        if (user_agent && json_is_string(user_agent))
1395
                                user_agent_text = json_string_value(user_agent);
1396

    
1397
                        /* Now the user part, if needed */
1398
                        json_t *username = json_object_get(root, "username");
1399
                        if(!guest && !username) {
1400
                                /* The username is mandatory if we're not registering as guests */
1401
                                JANUS_LOG(LOG_ERR, "Missing element (username)\n");
1402
                                error_code = JANUS_SIP_ERROR_MISSING_ELEMENT;
1403
                                g_snprintf(error_cause, 512, "Missing element (username)");
1404
                                goto error;
1405
                        }
1406
                        const char *username_text = NULL;
1407
                        janus_sip_uri_t username_uri;
1408
                        char user_id[256];
1409
                        if(username) {
1410
                                /* Parse address */
1411
                                username_text = json_string_value(username);
1412
                                if (janus_sip_parse_uri(&username_uri, username_text) < 0) {
1413
                                        JANUS_LOG(LOG_ERR, "Invalid user address %s\n", username_text);
1414
                                        error_code = JANUS_SIP_ERROR_INVALID_ADDRESS;
1415
                                        g_snprintf(error_cause, 512, "Invalid user address %s\n", username_text);
1416
                                        goto error;
1417
                                }
1418
                                g_strlcpy(user_id, username_uri.url->url_user, sizeof(user_id));
1419
                        }
1420
                        if(guest) {
1421
                                /* Not needed, we can stop here: just pick a random username if it wasn't provided and say we're registered */
1422
                                if(!username)
1423
                                        g_snprintf(user_id, 255, "janus-sip-%"SCNu32"", janus_random_uint32());
1424
                                JANUS_LOG(LOG_INFO, "Guest will have username %s\n", user_id);
1425
                                send_register = FALSE;
1426
                        } else {
1427
                                json_t *secret = json_object_get(root, "secret");
1428
                                json_t *ha1_secret = json_object_get(root, "ha1_secret");
1429
                                json_t *authuser = json_object_get(root, "authuser");
1430
                                if(!secret && !ha1_secret) {
1431
                                        JANUS_LOG(LOG_ERR, "Missing element (secret or ha1_secret)\n");
1432
                                        error_code = JANUS_SIP_ERROR_MISSING_ELEMENT;
1433
                                        g_snprintf(error_cause, 512, "Missing element (secret or ha1_secret)");
1434
                                        goto error;
1435
                                }
1436
                                if(secret && ha1_secret) {
1437
                                        JANUS_LOG(LOG_ERR, "Conflicting elements specified (secret and ha1_secret)\n");
1438
                                        error_code = JANUS_SIP_ERROR_INVALID_ELEMENT;
1439
                                        g_snprintf(error_cause, 512, "Conflicting elements specified (secret and ha1_secret)");
1440
                                        goto error;
1441
                                }
1442
                                const char *secret_text;
1443
                                if(secret) {
1444
                                        secret_text = json_string_value(secret);
1445
                                        session->account.secret = g_strdup(secret_text);
1446
                                        session->account.secret_type = janus_sip_secret_type_plaintext;
1447
                                } else {
1448
                                        secret_text = json_string_value(ha1_secret);
1449
                                        session->account.secret = g_strdup(secret_text);
1450
                                        session->account.secret_type = janus_sip_secret_type_hashed;
1451
                                }
1452
                                if (authuser) {
1453
                                        const char *authuser_text;
1454
                                        authuser_text = json_string_value(authuser);
1455
                                        session->account.authuser = g_strdup(authuser_text);
1456
                                } else {
1457
                                        session->account.authuser = g_strdup(user_id);
1458
                                }
1459
                                /* Got the values, try registering now */
1460
                                JANUS_LOG(LOG_VERB, "Registering user %s (secret %s) @ %s through %s\n",
1461
                                        username_text, secret_text, username_uri.url->url_host, proxy_text != NULL ? proxy_text : "(null)");
1462
                        }
1463

    
1464
                        session->account.identity = g_strdup(username_text);
1465
                        session->account.sips = sips;
1466
                        session->account.username = g_strdup(user_id);
1467
                        if (display_name_text) {
1468
                                session->account.display_name = g_strdup(display_name_text);
1469
                        }
1470
                        if (user_agent_text) {
1471
                                session->account.user_agent = g_strdup(user_agent_text);
1472
                        }
1473
                        if (proxy_text) {
1474
                                session->account.proxy = g_strdup(proxy_text);
1475
                        }
1476

    
1477
                        session->account.registration_status = janus_sip_registration_status_registering;
1478
                        if(session->stack == NULL) {
1479
                                /* Start the thread first */
1480
                                GError *error = NULL;
1481
                                g_thread_try_new("worker", janus_sip_sofia_thread, session, &error);
1482
                                if(error != NULL) {
1483
                                        JANUS_LOG(LOG_ERR, "Got error %d (%s) trying to launch the SIP Sofia thread...\n", error->code, error->message ? error->message : "??");
1484
                                        error_code = JANUS_SIP_ERROR_UNKNOWN_ERROR;
1485
                                        g_snprintf(error_cause, 512, "Got error %d (%s) trying to launch the SIP Sofia thread", error->code, error->message ? error->message : "??");
1486
                                        goto error;
1487
                                }
1488
                                long int timeout = 0;
1489
                                while(session->stack == NULL || session->stack->s_nua == NULL) {
1490
                                        g_usleep(100000);
1491
                                        timeout += 100000;
1492
                                        if(timeout >= 2000000) {
1493
                                                break;
1494
                                        }
1495
                                }
1496
                                if(timeout >= 2000000) {
1497
                                        JANUS_LOG(LOG_ERR, "Two seconds passed and still no NUA, problems with the thread?\n");
1498
                                        error_code = JANUS_SIP_ERROR_UNKNOWN_ERROR;
1499
                                        g_snprintf(error_cause, 512, "Two seconds passed and still no NUA, problems with the thread?");
1500
                                        goto error;
1501
                                }
1502
                        }
1503
                        if(session->stack->s_nh_r != NULL) {
1504
                                nua_handle_destroy(session->stack->s_nh_r);
1505
                                session->stack->s_nh_r = NULL;
1506
                        }
1507

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

    
2135
                        char payload[64];
2136
                        g_snprintf(payload, sizeof(payload), "Signal=%s\r\nDuration=%d", digit_text, duration_ms);
2137
                        nua_info(session->stack->s_nh_i,
2138
                                SIPTAG_CONTENT_TYPE_STR("application/dtmf-relay"),
2139
                                SIPTAG_PAYLOAD_STR(payload),
2140
                                TAG_END());
2141
                } else {
2142
                        JANUS_LOG(LOG_ERR, "Unknown request (%s)\n", request_text);
2143
                        error_code = JANUS_SIP_ERROR_INVALID_REQUEST;
2144
                        g_snprintf(error_cause, 512, "Unknown request (%s)", request_text);
2145
                        goto error;
2146
                }
2147

    
2148
                json_decref(root);
2149
                /* Prepare JSON event */
2150
                json_t *event = json_object();
2151
                json_object_set_new(event, "sip", json_string("event"));
2152
                if(result != NULL)
2153
                        json_object_set_new(event, "result", result);
2154
                char *event_text = json_dumps(event, JSON_INDENT(3) | JSON_PRESERVE_ORDER);
2155
                json_decref(event);
2156
                JANUS_LOG(LOG_VERB, "Pushing event: %s\n", event_text);
2157
                int ret = gateway->push_event(msg->handle, &janus_sip_plugin, msg->transaction, event_text, sdp_type, sdp);
2158
                JANUS_LOG(LOG_VERB, "  >> %d (%s)\n", ret, janus_get_api_error(ret));
2159
                g_free(event_text);
2160
                if(sdp)
2161
                        g_free(sdp);
2162
                janus_sip_message_free(msg);
2163
                continue;
2164

    
2165
error:
2166
                {
2167
                        if(root != NULL)
2168
                                json_decref(root);
2169
                        /* Prepare JSON error event */
2170
                        json_t *event = json_object();
2171
                        json_object_set_new(event, "sip", json_string("event"));
2172
                        json_object_set_new(event, "error_code", json_integer(error_code));
2173
                        json_object_set_new(event, "error", json_string(error_cause));
2174
                        char *event_text = json_dumps(event, JSON_INDENT(3) | JSON_PRESERVE_ORDER);
2175
                        json_decref(event);
2176
                        JANUS_LOG(LOG_VERB, "Pushing event: %s\n", event_text);
2177
                        int ret = gateway->push_event(msg->handle, &janus_sip_plugin, msg->transaction, event_text, NULL, NULL);
2178
                        JANUS_LOG(LOG_VERB, "  >> %d (%s)\n", ret, janus_get_api_error(ret));
2179
                        g_free(event_text);
2180
                        janus_sip_message_free(msg);
2181
                }
2182
        }
2183
        JANUS_LOG(LOG_VERB, "Leaving SIP handler thread\n");
2184
        return NULL;
2185
}
2186

    
2187

    
2188
/* Sofia callbacks */
2189
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[])
2190
{
2191
        janus_sip_session *session = (janus_sip_session *)magic;
2192
        ssip_t *ssip = session->stack;
2193
        switch (event) {
2194
        /* Status or Error Indications */
2195
                case nua_i_active:
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_error:
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_fork:
2202
                        JANUS_LOG(LOG_VERB, "[%s][%s]: %d %s\n", session->account.username, nua_event_name(event), status, phrase ? phrase : "??");
2203
                        break;
2204
                case nua_i_media_error:
2205
                        JANUS_LOG(LOG_VERB, "[%s][%s]: %d %s\n", session->account.username, nua_event_name(event), status, phrase ? phrase : "??");
2206
                        break;
2207
                case nua_i_subscription:
2208
                        JANUS_LOG(LOG_VERB, "[%s][%s]: %d %s\n", session->account.username, nua_event_name(event), status, phrase ? phrase : "??");
2209
                        break;
2210
                case nua_i_state:
2211
                        JANUS_LOG(LOG_VERB, "[%s][%s]: %d %s\n", session->account.username, nua_event_name(event), status, phrase ? phrase : "??");
2212
                        tagi_t const *ti = tl_find(tags, nutag_callstate);
2213
                        enum nua_callstate callstate = ti ? ti->t_value : -1;
2214
                        /* There are several call states, but we care about the terminated state in order to send the 'hangup' event
2215
                         * and the proceeding state in order to send the 'proceeding' event so the client can play a ringback tone for
2216
                         * the user since we don't send early media. (assuming this is the right session, of course).
2217
                         * http://sofia-sip.sourceforge.net/refdocs/nua/nua__tag_8h.html#a516dc237722dc8ca4f4aa3524b2b444b
2218
                         */
2219
                        if (callstate == nua_callstate_proceeding &&
2220
                                    (session->stack->s_nh_i == nh || session->stack->s_nh_i == NULL)) {
2221
                                json_t *call = json_object();
2222
                                json_object_set_new(call, "sip", json_string("event"));
2223
                                json_t *calling = json_object();
2224
                                json_object_set_new(calling, "event", json_string("proceeding"));
2225
                                json_object_set_new(calling, "code", json_integer(status));
2226
                                json_object_set_new(call, "result", calling);
2227
                                char *call_text = json_dumps(call, JSON_INDENT(3) | JSON_PRESERVE_ORDER);
2228
                                json_decref(call);
2229
                                JANUS_LOG(LOG_VERB, "Pushing event: %s\n", call_text);
2230
                                int ret = gateway->push_event(session->handle, &janus_sip_plugin, session->transaction, call_text, NULL, NULL);
2231
                                JANUS_LOG(LOG_VERB, "  >> %d (%s)\n", ret, janus_get_api_error(ret));
2232
                                g_free(call_text);
2233
                        } else if(callstate == nua_callstate_terminated &&
2234
                                        (session->stack->s_nh_i == nh || session->stack->s_nh_i == NULL)) {
2235
                                session->status = janus_sip_call_status_idle;
2236
                                session->stack->s_nh_i = NULL;
2237
                                json_t *call = json_object();
2238
                                json_object_set_new(call, "sip", json_string("event"));
2239
                                json_t *calling = json_object();
2240
                                json_object_set_new(calling, "event", json_string("hangup"));
2241
                                json_object_set_new(calling, "code", json_integer(status));
2242
                                json_object_set_new(calling, "reason", json_string(phrase ? phrase : "???"));
2243
                                json_object_set_new(call, "result", calling);
2244
                                char *call_text = json_dumps(call, JSON_INDENT(3) | JSON_PRESERVE_ORDER);
2245
                                json_decref(call);
2246
                                JANUS_LOG(LOG_VERB, "Pushing event: %s\n", call_text);
2247
                                int ret = gateway->push_event(session->handle, &janus_sip_plugin, session->transaction, call_text, NULL, NULL);
2248
                                JANUS_LOG(LOG_VERB, "  >> %d (%s)\n", ret, janus_get_api_error(ret));
2249
                                g_free(call_text);
2250
                                /* Get rid of any PeerConnection that may have been set up */
2251
                                if(session->transaction)
2252
                                        g_free(session->transaction);
2253
                                session->transaction = NULL;
2254
                                gateway->close_pc(session->handle);
2255
                        }
2256
                        break;
2257
                case nua_i_terminated:
2258
                        JANUS_LOG(LOG_VERB, "[%s][%s]: %d %s\n", session->account.username, nua_event_name(event), status, phrase ? phrase : "??");
2259
                        break;
2260
        /* SIP requests */
2261
                case nua_i_ack:
2262
                        JANUS_LOG(LOG_VERB, "[%s][%s]: %d %s\n", session->account.username, nua_event_name(event), status, phrase ? phrase : "??");
2263
                        break;
2264
                case nua_i_outbound:
2265
                        JANUS_LOG(LOG_VERB, "[%s][%s]: %d %s\n", session->account.username, nua_event_name(event), status, phrase ? phrase : "??");
2266
                        break;
2267
                case nua_i_bye: {
2268
                        JANUS_LOG(LOG_VERB, "[%s][%s]: %d %s\n", session->account.username, nua_event_name(event), status, phrase ? phrase : "??");
2269
                        break;
2270
                }
2271
                case nua_i_cancel: {
2272
                        JANUS_LOG(LOG_VERB, "[%s][%s]: %d %s\n", session->account.username, nua_event_name(event), status, phrase ? phrase : "??");
2273
                        break;
2274
                }
2275
                case nua_i_invite: {
2276
                        JANUS_LOG(LOG_VERB, "[%s][%s]: %d %s\n", session->account.username, nua_event_name(event), status, phrase ? phrase : "??");
2277
                        if(ssip == NULL) {
2278
                                JANUS_LOG(LOG_ERR, "\tInvalid SIP stack\n");
2279
                                nua_respond(nh, 500, sip_status_phrase(500), TAG_END());
2280
                                break;
2281
                        }
2282
                        sdp_parser_t *parser = sdp_parse(ssip->s_home, sip->sip_payload->pl_data, sip->sip_payload->pl_len, 0);
2283
                        if(!sdp_session(parser)) {
2284
                                JANUS_LOG(LOG_ERR, "\tError parsing SDP!\n");
2285
                                nua_respond(nh, 488, sip_status_phrase(488), TAG_END());
2286
                                sdp_parser_free(parser);
2287
                                break;
2288
                        }
2289
                        if(session->stack->s_nh_i != NULL) {
2290
                                if(session->stack->s_nh_i == nh) {
2291
                                        if (sdp_session_cmp(sdp_session(session->raw_media), sdp_session(parser)) == 0) {
2292
                                                /* re-INVITE that is basically a session-refresh (no media-change needed), accept. */
2293
                                                nua_respond(nh, 200, sip_status_phrase(200), TAG_END());
2294
                                        } else {
2295
                                                /* re-INVITE, we don't support those. */
2296
                                                nua_respond(nh, 488, sip_status_phrase(488), TAG_END());
2297
                                        }
2298
                                } else if(session->status >= janus_sip_call_status_inviting) {
2299
                                        /* Busy with another call */
2300
                                        JANUS_LOG(LOG_VERB, "\tAlready in a call (busy, status=%s)\n", janus_sip_call_status_string(session->status));
2301
                                        nua_respond(nh, 486, sip_status_phrase(486), TAG_END());
2302
                                        /* Notify the web app about the missed invite */
2303
                                        json_t *missed = json_object();
2304
                                        json_object_set_new(missed, "sip", json_string("event"));
2305
                                        json_t *result = json_object();
2306
                                        json_object_set_new(result, "event", json_string("missed_call"));
2307
                                        char *caller_text = url_as_string(session->stack->s_home, sip->sip_from->a_url);
2308
                                        json_object_set_new(result, "caller", json_string(caller_text));
2309
                                        su_free(session->stack->s_home, caller_text);
2310
                                        if (sip->sip_from && sip->sip_from->a_display) {
2311
                                                json_object_set_new(result, "displayname", json_string(sip->sip_from->a_display));
2312
                                        }
2313
                                        json_object_set_new(missed, "result", result);
2314
                                        char *missed_text = json_dumps(missed, JSON_INDENT(3) | JSON_PRESERVE_ORDER);
2315
                                        json_decref(missed);
2316
                                        JANUS_LOG(LOG_VERB, "Pushing event to peer: %s\n", missed_text);
2317
                                        int ret = gateway->push_event(session->handle, &janus_sip_plugin, session->transaction, missed_text, NULL, NULL);
2318
                                        JANUS_LOG(LOG_VERB, "  >> %d (%s)\n", ret, janus_get_api_error(ret));
2319
                                        g_free(missed_text);
2320
                                }
2321
                                sdp_parser_free(parser);
2322
                                break;
2323
                        }
2324
                        /* New incoming call */
2325
                        session->callee = g_strdup(url_as_string(session->stack->s_home, sip->sip_from->a_url));
2326
                        session->status = janus_sip_call_status_invited;
2327
                        /* Clean up SRTP stuff from before first, in case it's still needed */
2328
                        janus_sip_srtp_cleanup(session);
2329
                        /* Parse SDP */
2330
                        char *fixed_sdp = g_strdup(sip->sip_payload->pl_data);
2331
                        JANUS_LOG(LOG_VERB, "Someone is inviting us in a call:\n%s", sip->sip_payload->pl_data);
2332
                        sdp_session_t *sdp = sdp_session(parser);
2333
                        janus_sip_sdp_process(session, sdp, FALSE);
2334
                        /* Send SDP to the browser */
2335
                        json_t *call = json_object();
2336
                        json_object_set_new(call, "sip", json_string("event"));
2337
                        json_t *calling = json_object();
2338
                        json_object_set_new(calling, "event", json_string("incomingcall"));
2339
                        json_object_set_new(calling, "username", json_string(session->callee));
2340
                        if(sip->sip_from && sip->sip_from->a_display) {
2341
                                json_object_set_new(calling, "displayname", json_string(sip->sip_from->a_display));
2342
                        }
2343
                        if(session->media.has_srtp_remote) {
2344
                                /* FIXME Maybe a true/false instead? */
2345
                                json_object_set_new(calling, "srtp", json_string(session->media.require_srtp ? "sdes_mandatory" : "sdes_optional"));
2346
                        }
2347
                        json_object_set_new(call, "result", calling);
2348
                        char *call_text = json_dumps(call, JSON_INDENT(3) | JSON_PRESERVE_ORDER);
2349
                        json_decref(call);
2350
                        JANUS_LOG(LOG_VERB, "Pushing event to peer: %s\n", call_text);
2351
                        int ret = gateway->push_event(session->handle, &janus_sip_plugin, session->transaction, call_text, "offer", fixed_sdp);
2352
                        JANUS_LOG(LOG_VERB, "  >> %d (%s)\n", ret, janus_get_api_error(ret));
2353
                        g_free(call_text);
2354
                        g_free(fixed_sdp);
2355
                        sdp_parser_free(parser);
2356
                        /* Send a Ringing back */
2357
                        nua_respond(nh, 180, sip_status_phrase(180), TAG_END());
2358
                        session->stack->s_nh_i = nh;
2359
                        break;
2360
                }
2361
                case nua_i_options:
2362
                        JANUS_LOG(LOG_VERB, "[%s][%s]: %d %s\n", session->account.username, nua_event_name(event), status, phrase ? phrase : "??");
2363
                        /* FIXME Should we handle this message? for now we reply with a 405 Method Not Implemented */
2364
                        nua_respond(nh, 405, sip_status_phrase(405), TAG_END());
2365
                        break;
2366
        /* Responses */
2367
                case nua_r_get_params:
2368
                        JANUS_LOG(LOG_VERB, "[%s][%s]: %d %s\n", session->account.username, nua_event_name(event), status, phrase ? phrase : "??");
2369
                        break;
2370
                case nua_r_set_params:
2371
                        JANUS_LOG(LOG_VERB, "[%s][%s]: %d %s\n", session->account.username, nua_event_name(event), status, phrase ? phrase : "??");
2372
                        break;
2373
                case nua_r_notifier:
2374
                        JANUS_LOG(LOG_VERB, "[%s][%s]: %d %s\n", session->account.username, nua_event_name(event), status, phrase ? phrase : "??");
2375
                        break;
2376
                case nua_r_shutdown:
2377
                        JANUS_LOG(LOG_VERB, "[%s][%s]: %d %s\n", session->account.username, nua_event_name(event), status, phrase ? phrase : "??");
2378
                        if(status < 200 && !g_atomic_int_get(&stopping)) {
2379
                                /* shutdown in progress -> return */
2380
                                break;
2381
                        }
2382
                        if(ssip != NULL) {
2383
                                /* end the event loop. su_root_run() will return */
2384
                                su_root_break(ssip->s_root);
2385
                        }
2386
                        break;
2387
                case nua_r_terminate:
2388
                        JANUS_LOG(LOG_VERB, "[%s][%s]: %d %s\n", session->account.username, nua_event_name(event), status, phrase ? phrase : "??");
2389
                        break;
2390
        /* SIP responses */
2391
                case nua_r_bye:
2392
                        JANUS_LOG(LOG_VERB, "[%s][%s]: %d %s\n", session->account.username, nua_event_name(event), status, phrase ? phrase : "??");
2393
                        break;
2394
                case nua_r_cancel:
2395
                        JANUS_LOG(LOG_VERB, "[%s][%s]: %d %s\n", session->account.username, nua_event_name(event), status, phrase ? phrase : "??");
2396
                        break;
2397
                case nua_r_info:
2398
                        JANUS_LOG(LOG_VERB, "[%s][%s]: %d %s\n", session->account.username, nua_event_name(event), status, phrase ? phrase : "??");
2399
                        break;
2400
                case nua_r_invite: {
2401
                        JANUS_LOG(LOG_VERB, "[%s][%s]: %d %s\n", session->account.username, nua_event_name(event), status, phrase ? phrase : "??");
2402

    
2403
                        if(status < 200) {
2404
                                /* Not ready yet (FIXME May this be pranswer?? we don't handle it yet...) */
2405
                                break;
2406
                        } else if(status == 401 || status == 407) {
2407
                                char auth[256];
2408
                                const char* scheme;
2409
                                const char* realm;
2410
                                if(status == 401) {
2411
                                         /* Get scheme/realm from 401 error */
2412
                                        sip_www_authenticate_t const* www_auth = sip->sip_www_authenticate;
2413
                                        scheme = www_auth->au_scheme;
2414
                                        realm = msg_params_find(www_auth->au_params, "realm=");
2415
                                } else {
2416
                                         /* Get scheme/realm from 407 error, proxy-auth */
2417
                                        sip_proxy_authenticate_t const* proxy_auth = sip->sip_proxy_authenticate;
2418
                                        scheme = proxy_auth->au_scheme;
2419
                                        realm = msg_params_find(proxy_auth->au_params, "realm=");
2420
                                }
2421
                                memset(auth, 0, sizeof(auth));
2422
                                g_snprintf(auth, sizeof(auth), "%s%s:%s:%s:%s%s",
2423
                                        session->account.secret_type == janus_sip_secret_type_hashed ? "HA1+" : "",
2424
                                        scheme,
2425
                                        realm,
2426
                                        session->account.authuser ? session->account.authuser : "null",
2427
                                        session->account.secret_type == janus_sip_secret_type_hashed ? "HA1+" : "",
2428
                                        session->account.secret ? session->account.secret : "null");
2429
                                JANUS_LOG(LOG_VERB, "\t%s\n", auth);
2430
                                /* Authenticate */
2431
                                nua_authenticate(nh,
2432
                                        NUTAG_AUTH(auth),
2433
                                        TAG_END());
2434
                                break;
2435
                        } else if(status >= 400) {
2436
                                break;
2437
                        }
2438
                        if(ssip == NULL) {
2439
                                JANUS_LOG(LOG_ERR, "\tInvalid SIP stack\n");
2440
                                nua_respond(nh, 500, sip_status_phrase(500), TAG_END());
2441
                                break;
2442
                        }
2443
                        sdp_parser_t *parser = sdp_parse(ssip->s_home, sip->sip_payload->pl_data, sip->sip_payload->pl_len, 0);
2444
                        if(!sdp_session(parser)) {
2445
                                JANUS_LOG(LOG_ERR, "\tError parsing SDP!\n");
2446
                                nua_respond(nh, 488, sip_status_phrase(488), TAG_END());
2447
                                sdp_parser_free(parser);
2448
                                break;
2449
                        }
2450
                        /* Send an ACK, if needed */
2451
                        if(!session->media.autoack) {
2452
                                char *route = sip->sip_record_route ? url_as_string(session->stack->s_home, sip->sip_record_route->r_url) : NULL;
2453
                                JANUS_LOG(LOG_INFO, "Sending ACK (route=%s)\n", route ? route : "none");
2454
                                nua_ack(nh,
2455
                                        TAG_IF(route, NTATAG_DEFAULT_PROXY(route)),
2456
                                        TAG_END());
2457
                        }
2458
                        /* Parse SDP */
2459
                        JANUS_LOG(LOG_VERB, "Peer accepted our call:\n%s", sip->sip_payload->pl_data);
2460
                        session->status = janus_sip_call_status_incall;
2461
                        char *fixed_sdp = g_strdup(sip->sip_payload->pl_data);
2462
                        sdp_session_t *sdp = sdp_session(parser);
2463
                        janus_sip_sdp_process(session, sdp, TRUE);
2464
                        /* If we asked for SRTP and are not getting it, fail */
2465
                        if(session->media.require_srtp && !session->media.has_srtp_remote) {
2466
                                JANUS_LOG(LOG_ERR, "\tWe asked for mandatory SRTP but didn't get any in the reply!\n");
2467
                                sdp_parser_free(parser);
2468
                                g_free(fixed_sdp);
2469
                                /* Hangup immediately */
2470
                                session->status = janus_sip_call_status_closing;
2471
                                nua_bye(nh, TAG_END());
2472
                                g_free(session->callee);
2473
                                session->callee = NULL;
2474
                                break;
2475
                        }
2476
                        if(session->media.audio_pt > -1) {
2477
                                session->media.audio_pt_name = janus_get_codec_from_pt(fixed_sdp, session->media.audio_pt);
2478
                                JANUS_LOG(LOG_VERB, "Detected audio codec: %d (%s)\n", session->media.audio_pt, session->media.audio_pt_name);
2479
                        }
2480
                        if(session->media.video_pt > -1) {
2481
                                session->media.video_pt_name = janus_get_codec_from_pt(fixed_sdp, session->media.video_pt);
2482
                                JANUS_LOG(LOG_VERB, "Detected video codec: %d (%s)\n", session->media.video_pt, session->media.video_pt_name);
2483
                        }
2484
                        session->media.ready = 1;        /* FIXME Maybe we need a better way to signal this */
2485
                        if(session->raw_media != NULL)
2486
                                sdp_parser_free(session->raw_media);
2487
                        session->raw_media = parser;
2488
                        GError *error = NULL;
2489
                        g_thread_try_new("janus rtp handler", janus_sip_relay_thread, session, &error);
2490
                        if(error != NULL) {
2491
                                JANUS_LOG(LOG_ERR, "Got error %d (%s) trying to launch the RTP/RTCP thread...\n", error->code, error->message ? error->message : "??");
2492
                        }
2493
                        /* Send SDP to the browser */
2494
                        json_t *call = json_object();
2495
                        json_object_set_new(call, "sip", json_string("event"));
2496
                        json_t *calling = json_object();
2497
                        json_object_set_new(calling, "event", json_string("accepted"));
2498
                        json_object_set_new(calling, "username", json_string(session->callee));
2499
                        json_object_set_new(call, "result", calling);
2500
                        char *call_text = json_dumps(call, JSON_INDENT(3) | JSON_PRESERVE_ORDER);
2501
                        json_decref(call);
2502
                        JANUS_LOG(LOG_VERB, "Pushing event to peer: %s\n", call_text);
2503
                        int ret = gateway->push_event(session->handle, &janus_sip_plugin, session->transaction, call_text, "answer", fixed_sdp);
2504
                        JANUS_LOG(LOG_VERB, "  >> %d (%s)\n", ret, janus_get_api_error(ret));
2505
                        g_free(call_text);
2506
                        g_free(fixed_sdp);
2507
                        break;
2508
                }
2509
                case nua_r_register: {
2510
                        JANUS_LOG(LOG_VERB, "[%s][%s]: %d %s\n", session->account.username, nua_event_name(event), status, phrase ? phrase : "??");
2511
                        if(status == 200) {
2512
                                if(session->account.registration_status < janus_sip_registration_status_registered)
2513
                                        session->account.registration_status = janus_sip_registration_status_registered;
2514
                                JANUS_LOG(LOG_VERB, "Successfully registered\n");
2515
                                /* Notify the browser */
2516
                                json_t *call = json_object();
2517
                                json_object_set_new(call, "sip", json_string("event"));
2518
                                json_t *calling = json_object();
2519
                                json_object_set_new(calling, "event", json_string("registered"));
2520
                                json_object_set_new(calling, "username", json_string(session->account.username));
2521
                                json_object_set_new(calling, "register_sent", json_string("true"));
2522
                                json_object_set_new(call, "result", calling);
2523
                                char *call_text = json_dumps(call, JSON_INDENT(3) | JSON_PRESERVE_ORDER);
2524
                                json_decref(call);
2525
                                JANUS_LOG(LOG_VERB, "Pushing event: %s\n", call_text);
2526
                                int ret = gateway->push_event(session->handle, &janus_sip_plugin, session->transaction, call_text, NULL, NULL);
2527
                                JANUS_LOG(LOG_VERB, "  >> %d (%s)\n", ret, janus_get_api_error(ret));
2528
                                g_free(call_text);
2529
                        } else if(status == 401) {
2530
                                /* Get scheme/realm from 401 error */
2531
                                sip_www_authenticate_t const* www_auth = sip->sip_www_authenticate;
2532
                                char const* scheme = www_auth->au_scheme;
2533
                                const char* realm = msg_params_find(www_auth->au_params, "realm=");
2534
                                char auth[256];
2535
                                memset(auth, 0, sizeof(auth));
2536
                                g_snprintf(auth, sizeof(auth), "%s%s:%s:%s:%s%s",
2537
                                        session->account.secret_type == janus_sip_secret_type_hashed ? "HA1+" : "",
2538
                                        scheme,
2539
                                        realm,
2540
                                        session->account.authuser ? session->account.authuser : "null",
2541
                                        session->account.secret_type == janus_sip_secret_type_hashed ? "HA1+" : "",
2542
                                        session->account.secret);
2543
                                JANUS_LOG(LOG_VERB, "\t%s\n", auth);
2544
                                /* Authenticate */
2545
                                nua_authenticate(nh,
2546
                                        NUTAG_AUTH(auth),
2547
                                        TAG_END());
2548
                        } else if(status >= 400) {
2549
                                /* Authentication failed? */
2550
                                session->account.registration_status = janus_sip_registration_status_failed;
2551
                                /* Tell the browser... */
2552
                                json_t *event = json_object();
2553
                                json_object_set_new(event, "sip", json_string("event"));
2554
                                json_t *result = json_object();
2555
                                json_object_set_new(result, "event", json_string("registration_failed"));
2556
                                json_object_set_new(result, "code", json_integer(status));
2557
                                json_object_set_new(result, "reason", json_string(phrase ? phrase : ""));
2558
                                json_object_set_new(event, "result", result);
2559
                                char *event_text = json_dumps(event, JSON_INDENT(3) | JSON_PRESERVE_ORDER);
2560
                                json_decref(event);
2561
                                JANUS_LOG(LOG_VERB, "Pushing event: %s\n", event_text);
2562
                                int ret = gateway->push_event(session->handle, &janus_sip_plugin, session->transaction, event_text, NULL, NULL);
2563
                                JANUS_LOG(LOG_VERB, "  >> %d (%s)\n", ret, janus_get_api_error(ret));
2564
                                g_free(event_text);
2565
                        }
2566
                        break;
2567
                }
2568
                default:
2569
                        /* unknown event -> print out error message */
2570
                        JANUS_LOG(LOG_ERR, "Unknown event %d (%s)\n", event, nua_event_name(event));
2571
                        break;
2572
        }
2573
}
2574

    
2575
void janus_sip_sdp_process(janus_sip_session *session, sdp_session_t *sdp, gboolean answer) {
2576
        if(!session || !sdp)
2577
                return;
2578
        /* c= */
2579
        if(sdp->sdp_connection && sdp->sdp_connection->c_address) {
2580
                g_free(session->media.remote_ip);
2581
                session->media.remote_ip = g_strdup(sdp->sdp_connection->c_address);
2582
                JANUS_LOG(LOG_VERB, "  >> Media connection:\n");
2583
                JANUS_LOG(LOG_VERB, "       %s\n", session->media.remote_ip);
2584
        }
2585
        JANUS_LOG(LOG_VERB, "  >> Media lines:\n");
2586
        sdp_media_t *m = sdp->sdp_media;
2587
        while(m) {
2588
                session->media.require_srtp = session->media.require_srtp || (m->m_proto_name && !strcasecmp(m->m_proto_name, "RTP/SAVP"));
2589
                if(m->m_type == sdp_media_audio) {
2590
                        JANUS_LOG(LOG_VERB, "       Audio: %lu\n", m->m_port);
2591
                        if(m->m_port) {
2592
                                session->media.has_audio = 1;
2593
                                session->media.remote_audio_rtp_port = m->m_port;
2594
                                session->media.remote_audio_rtcp_port = m->m_port+1;        /* FIXME We're assuming RTCP is on the next port */
2595
                        }
2596
                } else if(m->m_type == sdp_media_video) {
2597
                        JANUS_LOG(LOG_VERB, "       Video: %lu\n", m->m_port);
2598
                        if(m->m_port) {
2599
                                session->media.has_video = 1;
2600
                                session->media.remote_video_rtp_port = m->m_port;
2601
                                session->media.remote_video_rtcp_port = m->m_port+1;        /* FIXME We're assuming RTCP is on the next port */
2602
                        }
2603
                } else {
2604
                        JANUS_LOG(LOG_WARN, "       Unsupported media line (not audio/video)\n");
2605
                        m = m->m_next;
2606
                        continue;
2607
                }
2608
                JANUS_LOG(LOG_VERB, "       Media connections:\n");
2609
                if(m->m_connections) {
2610
                        sdp_connection_t *c = m->m_connections;
2611
                        while(c) {
2612
                                if(c->c_address) {
2613
                                        g_free(session->media.remote_ip);
2614
                                        session->media.remote_ip = g_strdup(c->c_address);
2615
                                        JANUS_LOG(LOG_VERB, "         [%s]\n", session->media.remote_ip);
2616
                                }
2617
                                c = c->c_next;
2618
                        }
2619
                }
2620
                JANUS_LOG(LOG_VERB, "       Media RTP maps:\n");
2621
                sdp_rtpmap_t *r = m->m_rtpmaps;
2622
                while(r) {
2623
                        JANUS_LOG(LOG_VERB, "         [%u] %s\n", r->rm_pt, r->rm_encoding);
2624
                        r = r->rm_next;
2625
                }
2626
                JANUS_LOG(LOG_VERB, "       Media attributes:\n");
2627
                sdp_attribute_t *a = m->m_attributes;
2628
                while(a) {
2629
                        if(a->a_name) {
2630
                                if(!strcasecmp(a->a_name, "rtpmap")) {
2631
                                        JANUS_LOG(LOG_VERB, "         RTP Map:     %s\n", a->a_value);
2632
                                } else if(!strcasecmp(a->a_name, "crypto")) {
2633
                                        JANUS_LOG(LOG_VERB, "         Crypto:      %s\n", a->a_value);
2634
                                        if(m->m_type == sdp_media_audio || m->m_type == sdp_media_video) {
2635
                                                gint32 tag = 0;
2636
                                                int suite;
2637
                                                char crypto[40];
2638
                                                /* FIXME inline can be more complex than that, and we're currently only offering SHA1_80 */
2639
                                                int res = sscanf(a->a_value, "%"SCNi32" AES_CM_128_HMAC_SHA1_%2d inline:%40s",
2640
                                                        &tag, &suite, crypto);
2641
                                                if(res != 3) {
2642
                                                        JANUS_LOG(LOG_WARN, "Failed to parse crypto line, ignoring... %s\n", a->a_value);
2643
                                                } else {
2644
                                                        gboolean video = (m->m_type == sdp_media_video);
2645
                                                        int current_suite = video ? session->media.video_srtp_suite_in : session->media.audio_srtp_suite_in;
2646
                                                        if(current_suite == 0) {
2647
                                                                if(video)
2648
                                                                        session->media.video_srtp_suite_in = suite;
2649
                                                                else
2650
                                                                        session->media.audio_srtp_suite_in = suite;
2651
                                                                janus_sip_srtp_set_remote(session, video, crypto, suite);
2652
                                                                session->media.has_srtp_remote = TRUE;
2653
                                                        } else {
2654
                                                                JANUS_LOG(LOG_WARN, "We already configured a %s crypto context (AES_CM_128_HMAC_SHA1_%d), skipping additional crypto line\n",
2655
                                                                        video ? "video" : "audio", current_suite);
2656
                                                        }
2657
                                                }
2658
                                        }
2659
                                }
2660
                        }
2661
                        a = a->a_next;
2662
                }
2663
                if(answer && (m->m_type == sdp_media_audio || m->m_type == sdp_media_video)) {
2664
                        /* Check which codec was negotiated eventually */
2665
                        int pt = -1;
2666
                        if(!m->m_rtpmaps) {
2667
                                JANUS_LOG(LOG_VERB, "No RTP maps?? trying formats...\n");
2668
                                if(m->m_format) {
2669
                                        sdp_list_t *fmt = m->m_format;
2670
                                        pt = atoi(fmt->l_text);
2671
                                }
2672
                        } else {
2673
                                sdp_rtpmap_t *r = m->m_rtpmaps;
2674
                                pt = r->rm_pt;
2675
                        }
2676
                        if(pt > -1) {
2677
                                if(m->m_type == sdp_media_audio) {
2678
                                        session->media.audio_pt = pt;
2679
                                } else {
2680
                                        session->media.video_pt = pt;
2681
                                }
2682
                        }
2683
                }
2684
                m = m->m_next;
2685
        }
2686
}
2687

    
2688
char *janus_sip_sdp_manipulate(janus_sip_session *session, sdp_session_t *sdp, gboolean answer) {
2689
        if(!session || !session->stack || !sdp)
2690
                return NULL;
2691
        /* Placeholders for later */
2692
        sdp_attribute_t crypto_audio = {
2693
                .a_size = sizeof(sdp_attribute_t),
2694
                .a_name = "crypto",
2695
                .a_value = "audio"
2696
        };
2697
        sdp_attribute_t crypto_video = {
2698
                .a_size = sizeof(sdp_attribute_t),
2699
                .a_name = "crypto",
2700
                .a_value = "video"
2701
        };
2702
        /* Start replacing stuff */
2703
        if(sdp->sdp_connection && sdp->sdp_connection->c_address) {
2704
                sdp->sdp_connection->c_address = local_ip;
2705
        }
2706
        JANUS_LOG(LOG_VERB, "Setting protocol to %s\n", session->media.require_srtp ? "RTP/SAVP" : "RTP/AVP");
2707
        sdp_media_t *m = sdp->sdp_media;
2708
        while(m) {
2709
                m->m_proto = session->media.require_srtp ? sdp_proto_srtp : sdp_proto_rtp;
2710
                m->m_proto_name = session->media.require_srtp ? "RTP/SAVP" : "RTP/AVP";
2711
                if(m->m_type == sdp_media_audio) {
2712
                        m->m_port = session->media.local_audio_rtp_port;
2713
                        if(session->media.has_srtp_local) {
2714
                                sdp_attribute_append(&m->m_attributes, &crypto_audio);
2715
                        }
2716
                } else if(m->m_type == sdp_media_video) {
2717
                        m->m_port = session->media.local_video_rtp_port;
2718
                        if(session->media.has_srtp_local) {
2719
                                sdp_attribute_append(&m->m_attributes, &crypto_video);
2720
                        }
2721
                }
2722
                if(m->m_connections) {
2723
                        sdp_connection_t *c = m->m_connections;
2724
                        while(c) {
2725
                                c->c_address = local_ip;
2726
                                c = c->c_next;
2727
                        }
2728
                }
2729
                if(answer && (m->m_type == sdp_media_audio || m->m_type == sdp_media_video)) {
2730
                        /* Check which codec was negotiated eventually */
2731
                        int pt = -1;
2732
                        if(!m->m_rtpmaps) {
2733
                                JANUS_LOG(LOG_VERB, "No RTP maps?? trying formats...\n");
2734
                                if(m->m_format) {
2735
                                        sdp_list_t *fmt = m->m_format;
2736
                                        pt = atoi(fmt->l_text);
2737
                                }
2738
                        } else {
2739
                                sdp_rtpmap_t *r = m->m_rtpmaps;
2740
                                pt = r->rm_pt;
2741
                        }
2742
                        if(pt > -1) {
2743
                                if(m->m_type == sdp_media_audio) {
2744
                                        session->media.audio_pt = pt;
2745
                                } else {
2746
                                        session->media.video_pt = pt;
2747
                                }
2748
                        }
2749
                }
2750
                m = m->m_next;
2751
        }
2752
        /* Generate a SDP string out of our changes */
2753
        char buf[2048];
2754
        sdp_printer_t *printer = sdp_print(session->stack->s_home, sdp, buf, 2048, 0);
2755
        if(!sdp_message(printer)) {
2756
                sdp_printer_free(printer);
2757
                return NULL;
2758
        }
2759
        sdp_printer_free(printer);
2760
        char *new_sdp = g_strdup(buf);
2761
        /* If any crypto placeholer was there, fix that */
2762
        if(session->media.has_srtp_local) {
2763
                if(session->media.has_audio) {
2764
                        char *crypto = NULL;
2765
                        session->media.audio_srtp_suite_out = 80;
2766
                        janus_sip_srtp_set_local(session, FALSE, &crypto);
2767
                        /* FIXME 32? 80? Both? */
2768
                        char cryptoline[100];
2769
                        g_snprintf(cryptoline, 100, "a=crypto:1 AES_CM_128_HMAC_SHA1_80 inline:%s", crypto);
2770
                        g_free(crypto);
2771
                        new_sdp = janus_string_replace(new_sdp, "a=crypto:audio", cryptoline);
2772
                }
2773
                if(session->media.has_video) {
2774
                        char *crypto = NULL;
2775
                        session->media.video_srtp_suite_out = 80;
2776
                        janus_sip_srtp_set_local(session, TRUE, &crypto);
2777
                        /* FIXME 32? 80? Both? */
2778
                        char cryptoline[100];
2779
                        g_snprintf(cryptoline, 100, "a=crypto:1 AES_CM_128_HMAC_SHA1_80 inline:%s", crypto);
2780
                        g_free(crypto);
2781
                        new_sdp = janus_string_replace(new_sdp, "a=crypto:video", cryptoline);
2782
                }
2783
        }
2784
        return new_sdp;
2785
}
2786

    
2787
/* Bind local RTP/RTCP sockets */
2788
static int janus_sip_allocate_local_ports(janus_sip_session *session) {
2789
        if(session == NULL) {
2790
                JANUS_LOG(LOG_ERR, "Invalid session\n");
2791
                return -1;
2792
        }
2793
        /* Reset status */
2794
        if(session->media.audio_rtp_fd != -1) {
2795
                close(session->media.audio_rtp_fd);
2796
                session->media.audio_rtp_fd = -1;
2797
        }
2798
        if(session->media.audio_rtcp_fd != -1) {
2799
                close(session->media.audio_rtcp_fd);
2800
                session->media.audio_rtcp_fd = -1;
2801
        }
2802
        session->media.local_audio_rtp_port = 0;
2803
        session->media.local_audio_rtcp_port = 0;
2804
        session->media.audio_ssrc = 0;
2805
        if(session->media.video_rtp_fd != -1) {
2806
                close(session->media.video_rtp_fd);
2807
                session->media.video_rtp_fd = -1;
2808
        }
2809
        if(session->media.video_rtcp_fd != -1) {
2810
                close(session->media.video_rtcp_fd);
2811
                session->media.video_rtcp_fd = -1;
2812
        }
2813
        session->media.local_video_rtp_port = 0;
2814
        session->media.local_video_rtcp_port = 0;
2815
        session->media.video_ssrc = 0;
2816
        /* Start */
2817
        int attempts = 100;        /* FIXME Don't retry forever */
2818
        if(session->media.has_audio) {
2819
                JANUS_LOG(LOG_VERB, "Allocating audio ports:\n");
2820
                struct sockaddr_in audio_rtp_address, audio_rtcp_address;
2821
                while(session->media.local_audio_rtp_port == 0 || session->media.local_audio_rtcp_port == 0) {
2822
                        if(attempts == 0)        /* Too many failures */
2823
                                return -1;
2824
                        if(session->media.audio_rtp_fd == -1) {
2825
                                session->media.audio_rtp_fd = socket(AF_INET, SOCK_DGRAM, 0);
2826
                        }
2827
                        if(session->media.audio_rtcp_fd == -1) {
2828
                                session->media.audio_rtcp_fd = socket(AF_INET, SOCK_DGRAM, 0);
2829
                        }
2830
                        int rtp_port = g_random_int_range(10000, 60000);        /* FIXME Should this be configurable? */
2831
                        if(rtp_port % 2)
2832
                                rtp_port++;        /* Pick an even port for RTP */
2833
                        audio_rtp_address.sin_family = AF_INET;
2834
                        audio_rtp_address.sin_port = htons(rtp_port);
2835
                        inet_pton(AF_INET, local_ip, &audio_rtp_address.sin_addr.s_addr);
2836
                        if(bind(session->media.audio_rtp_fd, (struct sockaddr *)(&audio_rtp_address), sizeof(struct sockaddr)) < 0) {
2837
                                JANUS_LOG(LOG_ERR, "Bind failed for audio RTP (port %d), trying a different one...\n", rtp_port);
2838
                                attempts--;
2839
                                continue;
2840
                        }
2841
                        JANUS_LOG(LOG_VERB, "Audio RTP listener bound to port %d\n", rtp_port);
2842
                        int rtcp_port = rtp_port+1;
2843
                        audio_rtcp_address.sin_family = AF_INET;
2844
                        audio_rtcp_address.sin_port = htons(rtcp_port);
2845
                        inet_pton(AF_INET, local_ip, &audio_rtcp_address.sin_addr.s_addr);
2846
                        if(bind(session->media.audio_rtcp_fd, (struct sockaddr *)(&audio_rtcp_address), sizeof(struct sockaddr)) < 0) {
2847
                                JANUS_LOG(LOG_ERR, "Bind failed for audio RTCP (port %d), trying a different one...\n", rtcp_port);
2848
                                /* RTP socket is not valid anymore, reset it */
2849
                                close(session->media.audio_rtp_fd);
2850
                                session->media.audio_rtp_fd = -1;
2851
                                attempts--;
2852
                                continue;
2853
                        }
2854
                        JANUS_LOG(LOG_VERB, "Audio RTCP listener bound to port %d\n", rtcp_port);
2855
                        session->media.local_audio_rtp_port = rtp_port;
2856
                        session->media.local_audio_rtcp_port = rtcp_port;
2857
                }
2858
        }
2859
        if(session->media.has_video) {
2860
                JANUS_LOG(LOG_VERB, "Allocating video ports:\n");
2861
                struct sockaddr_in video_rtp_address, video_rtcp_address;
2862
                while(session->media.local_video_rtp_port == 0 || session->media.local_video_rtcp_port == 0) {
2863
                        if(attempts == 0)        /* Too many failures */
2864
                                return -1;
2865
                        if(session->media.video_rtp_fd == -1) {
2866
                                session->media.video_rtp_fd = socket(AF_INET, SOCK_DGRAM, 0);
2867
                        }
2868
                        if(session->media.video_rtcp_fd == -1) {
2869
                                session->media.video_rtcp_fd = socket(AF_INET, SOCK_DGRAM, 0);
2870
                        }
2871
                        int rtp_port = g_random_int_range(10000, 60000);        /* FIXME Should this be configurable? */
2872
                        if(rtp_port % 2)
2873
                                rtp_port++;        /* Pick an even port for RTP */
2874
                        video_rtp_address.sin_family = AF_INET;
2875
                        video_rtp_address.sin_port = htons(rtp_port);
2876
                        inet_pton(AF_INET, local_ip, &video_rtp_address.sin_addr.s_addr);
2877
                        if(bind(session->media.video_rtp_fd, (struct sockaddr *)(&video_rtp_address), sizeof(struct sockaddr)) < 0) {
2878
                                JANUS_LOG(LOG_ERR, "Bind failed for video RTP (port %d), trying a different one...\n", rtp_port);
2879
                                attempts--;
2880
                                continue;
2881
                        }
2882
                        JANUS_LOG(LOG_VERB, "Video RTP listener bound to port %d\n", rtp_port);
2883
                        int rtcp_port = rtp_port+1;
2884
                        video_rtcp_address.sin_family = AF_INET;
2885
                        video_rtcp_address.sin_port = htons(rtcp_port);
2886
                        inet_pton(AF_INET, local_ip, &video_rtcp_address.sin_addr.s_addr);
2887
                        if(bind(session->media.video_rtcp_fd, (struct sockaddr *)(&video_rtcp_address), sizeof(struct sockaddr)) < 0) {
2888
                                JANUS_LOG(LOG_ERR, "Bind failed for video RTCP (port %d), trying a different one...\n", rtcp_port);
2889
                                /* RTP socket is not valid anymore, reset it */
2890
                                close(session->media.video_rtp_fd);
2891
                                session->media.video_rtp_fd = -1;
2892
                                attempts--;
2893
                                continue;
2894
                        }
2895
                        JANUS_LOG(LOG_VERB, "Video RTCP listener bound to port %d\n", rtcp_port);
2896
                        session->media.local_video_rtp_port = rtp_port;
2897
                        session->media.local_video_rtcp_port = rtcp_port;
2898
                }
2899
        }
2900
        return 0;
2901
}
2902

    
2903
/* Thread to relay RTP/RTCP frames coming from the SIP peer */
2904
static void *janus_sip_relay_thread(void *data) {
2905
        janus_sip_session *session = (janus_sip_session *)data;
2906
        if(!session || !session->account.username || !session->callee) {
2907
                g_thread_unref(g_thread_self());
2908
                return NULL;
2909
        }
2910
        JANUS_LOG(LOG_VERB, "Starting relay thread (%s <--> %s)\n", session->account.username, session->callee);
2911

    
2912
        gboolean have_server_ip = TRUE;
2913
        struct sockaddr_in server_addr;
2914
        memset(&server_addr, 0, sizeof(server_addr));
2915
        server_addr.sin_family = AF_INET;
2916
        if((inet_aton(session->media.remote_ip, &server_addr.sin_addr)) <= 0) {        /* Not a numeric IP... */
2917
                struct hostent *host = gethostbyname(session->media.remote_ip);        /* ...resolve name */
2918
                if(!host) {
2919
                        JANUS_LOG(LOG_ERR, "[SIP-%s] Couldn't get host (%s)\n", session->account.username, session->media.remote_ip);
2920
                        have_server_ip = FALSE;
2921
                } else {
2922
                        server_addr.sin_addr = *(struct in_addr *)host->h_addr_list;
2923
                }
2924
        }
2925

    
2926
        /* Connect peers (FIXME This pretty much sucks right now) */
2927
        if(have_server_ip && session->media.remote_audio_rtp_port) {
2928
                server_addr.sin_port = htons(session->media.remote_audio_rtp_port);
2929
                if(connect(session->media.audio_rtp_fd, (struct sockaddr *)&server_addr, sizeof(struct sockaddr)) == -1) {
2930
                        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);
2931
                        JANUS_LOG(LOG_ERR, "[SIP-%s]   -- %d (%s)\n", session->account.username, errno, strerror(errno));
2932
                }
2933
        }
2934
        if(have_server_ip && session->media.remote_audio_rtcp_port) {
2935
                server_addr.sin_port = htons(session->media.remote_audio_rtcp_port);
2936
                if(connect(session->media.audio_rtcp_fd, (struct sockaddr *)&server_addr, sizeof(struct sockaddr)) == -1) {
2937
                        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);
2938
                        JANUS_LOG(LOG_ERR, "[SIP-%s]   -- %d (%s)\n", session->account.username, errno, strerror(errno));
2939
                }
2940
        }
2941
        if(have_server_ip && session->media.remote_video_rtp_port) {
2942
                server_addr.sin_port = htons(session->media.remote_video_rtp_port);
2943
                if(connect(session->media.video_rtp_fd, (struct sockaddr *)&server_addr, sizeof(struct sockaddr)) == -1) {
2944
                        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);
2945
                        JANUS_LOG(LOG_ERR, "[SIP-%s]   -- %d (%s)\n", session->account.username, errno, strerror(errno));
2946
                }
2947
        }
2948
        if(have_server_ip && session->media.remote_video_rtcp_port) {
2949
                server_addr.sin_port = htons(session->media.remote_video_rtcp_port);
2950
                if(connect(session->media.video_rtcp_fd, (struct sockaddr *)&server_addr, sizeof(struct sockaddr)) == -1) {
2951
                        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);
2952
                        JANUS_LOG(LOG_ERR, "[SIP-%s]   -- %d (%s)\n", session->account.username, errno, strerror(errno));
2953
                }
2954
        }
2955

    
2956
        if(!session->callee) {
2957
                JANUS_LOG(LOG_VERB, "[SIP-%s] Leaving thread, no callee...\n", session->account.username);
2958
                g_thread_unref(g_thread_self());
2959
                return NULL;
2960
        }
2961
        /* File descriptors */
2962
        socklen_t addrlen;
2963
        struct sockaddr_in remote;
2964
        int resfd = 0, bytes = 0;
2965
        struct pollfd fds[4];
2966
        char buffer[1500];
2967
        memset(buffer, 0, 1500);
2968
        /* Loop */
2969
        int num = 0;
2970
        gboolean goon = TRUE;
2971
        while(goon && session != NULL && !session->destroyed &&
2972
                        session->status > janus_sip_call_status_idle &&
2973
                        session->status < janus_sip_call_status_closing) {        /* FIXME We need a per-call watchdog as well */
2974
                /* Prepare poll */
2975
                num = 0;
2976
                if(session->media.audio_rtp_fd != -1) {
2977
                        fds[num].fd = session->media.audio_rtp_fd;
2978
                        fds[num].events = POLLIN;
2979
                        fds[num].revents = 0;
2980
                        num++;
2981
                }
2982
                if(session->media.audio_rtcp_fd != -1) {
2983
                        fds[num].fd = session->media.audio_rtcp_fd;
2984
                        fds[num].events = POLLIN;
2985
                        fds[num].revents = 0;
2986
                        num++;
2987
                }
2988
                if(session->media.video_rtp_fd != -1) {
2989
                        fds[num].fd = session->media.video_rtp_fd;
2990
                        fds[num].events = POLLIN;
2991
                        fds[num].revents = 0;
2992
                        num++;
2993
                }
2994
                if(session->media.video_rtcp_fd != -1) {
2995
                        fds[num].fd = session->media.video_rtcp_fd;
2996
                        fds[num].events = POLLIN;
2997
                        fds[num].revents = 0;
2998
                        num++;
2999
                }
3000
                /* Wait for some data */
3001
                resfd = poll(fds, num, 1000);
3002
                if(resfd < 0) {
3003
                        JANUS_LOG(LOG_ERR, "[SIP-%s] Error polling...\n", session->account.username);
3004
                        JANUS_LOG(LOG_ERR, "[SIP-%s]   -- %d (%s)\n", session->account.username, errno, strerror(errno));
3005
                        break;
3006
                } else if(resfd == 0) {
3007
                        /* No data, keep going */
3008
                        continue;
3009
                }
3010
                if(session == NULL || session->destroyed ||
3011
                                session->status <= janus_sip_call_status_idle ||
3012
                                session->status >= janus_sip_call_status_closing)
3013
                        break;
3014
                int i = 0;
3015
                for(i=0; i<num; i++) {
3016
                        if(fds[i].revents & (POLLERR | POLLHUP)) {
3017
                                /* Socket error? */
3018
                                JANUS_LOG(LOG_ERR, "[SIP-%s] Error polling: %s...\n", session->account.username,
3019
                                        fds[i].revents & POLLERR ? "POLLERR" : "POLLHUP");
3020
                                JANUS_LOG(LOG_ERR, "[SIP-%s]   -- %d (%s)\n", session->account.username, errno, strerror(errno));
3021
                                goon = FALSE;        /* Can we assume it's pretty much over, after a POLLERR? */
3022
                                /* FIXME Simulate a "hangup" coming from the browser */
3023
                                janus_sip_message *msg = g_malloc0(sizeof(janus_sip_message));
3024
                                msg->handle = session->handle;
3025
                                msg->message = g_strdup("{\"request\":\"hangup\"}");
3026
                                msg->transaction = NULL;
3027
                                msg->sdp_type = NULL;
3028
                                msg->sdp = NULL;
3029
                                g_async_queue_push(messages, msg);
3030
                                break;
3031
                        } else if(fds[i].revents & POLLIN) {
3032
                                /* Got an RTP/RTCP packet */
3033
                                if(session->media.audio_rtp_fd != -1 && fds[i].fd == session->media.audio_rtp_fd) {
3034
                                        /* Got something audio (RTP) */
3035
                                        addrlen = sizeof(remote);
3036
                                        bytes = recvfrom(session->media.audio_rtp_fd, buffer, 1500, 0, (struct sockaddr*)&remote, &addrlen);
3037
                                        //~ JANUS_LOG(LOG_VERB, "************************\nGot %d bytes on the audio RTP channel...\n", bytes);
3038
                                        //~ rtp_header_t *rtp = (rtp_header_t *)buffer;
3039
                                        //~ JANUS_LOG(LOG_VERB, " ... parsed RTP packet (ssrc=%u, pt=%u, seq=%u, ts=%u)...\n",
3040
                                                //~ ntohl(rtp->ssrc), rtp->type, ntohs(rtp->seq_number), ntohl(rtp->timestamp));
3041
                                        if(session->media.audio_ssrc_peer == 0) {
3042
                                                rtp_header *header = (rtp_header *)buffer;
3043
                                                session->media.audio_ssrc_peer = ntohl(header->ssrc);
3044
                                                JANUS_LOG(LOG_VERB, "Got SIP peer audio SSRC: %"SCNu32"\n", session->media.audio_ssrc_peer);
3045
                                        }
3046
                                        /* Is this SRTP? */
3047
                                        if(session->media.has_srtp_remote) {
3048
                                                int buflen = bytes;
3049
                                                err_status_t res = srtp_unprotect(session->media.audio_srtp_in, buffer, &buflen);
3050
                                                if(res != err_status_ok && res != err_status_replay_fail && res != err_status_replay_old) {
3051
                                                        rtp_header *header = (rtp_header *)buffer;
3052
                                                        guint32 timestamp = ntohl(header->timestamp);
3053
                                                        guint16 seq = ntohs(header->seq_number);
3054
                                                        JANUS_LOG(LOG_ERR, "[SIP-%s] Audio SRTP unprotect error: %s (len=%d-->%d, ts=%"SCNu32", seq=%"SCNu16")\n",
3055
                                                                session->account.username, janus_sip_get_srtp_error(res), bytes, buflen, timestamp, seq);
3056
                                                        continue;
3057
                                                }
3058
                                                bytes = buflen;
3059
                                        }
3060
                                        /* Save the frame if we're recording */
3061
                                        janus_recorder_save_frame(session->arc_peer, buffer, bytes);
3062
                                        /* Relay to browser */
3063
                                        gateway->relay_rtp(session->handle, 0, buffer, bytes);
3064
                                        continue;
3065
                                } else if(session->media.audio_rtcp_fd != -1 && fds[i].fd == session->media.audio_rtcp_fd) {
3066
                                        /* Got something audio (RTCP) */
3067
                                        addrlen = sizeof(remote);
3068
                                        bytes = recvfrom(session->media.audio_rtcp_fd, buffer, 1500, 0, (struct sockaddr*)&remote, &addrlen);
3069
                                        //~ JANUS_LOG(LOG_VERB, "************************\nGot %d bytes on the audio RTCP channel...\n", bytes);
3070
                                        /* Is this SRTCP? */
3071
                                        if(session->media.has_srtp_remote) {
3072
                                                int buflen = bytes;
3073
                                                err_status_t res = srtp_unprotect_rtcp(session->media.audio_srtp_in, buffer, &buflen);
3074
                                                if(res != err_status_ok && res != err_status_replay_fail && res != err_status_replay_old) {
3075
                                                        JANUS_LOG(LOG_ERR, "[SIP-%s] Audio SRTCP unprotect error: %s (len=%d-->%d)\n",
3076
                                                                session->account.username, janus_sip_get_srtp_error(res), bytes, buflen);
3077
                                                        continue;
3078
                                                }
3079
                                                bytes = buflen;
3080
                                        }
3081
                                        /* Relay to browser */
3082
                                        gateway->relay_rtcp(session->handle, 0, buffer, bytes);
3083
                                        continue;
3084
                                } else if(session->media.video_rtp_fd != -1 && fds[i].fd == session->media.video_rtp_fd) {
3085
                                        /* Got something video (RTP) */
3086
                                        addrlen = sizeof(remote);
3087
                                        bytes = recvfrom(session->media.video_rtp_fd, buffer, 1500, 0, (struct sockaddr*)&remote, &addrlen);
3088
                                        //~ JANUS_LOG(LOG_VERB, "************************\nGot %d bytes on the video RTP channel...\n", bytes);
3089
                                        //~ rtp_header_t *rtp = (rtp_header_t *)buffer;
3090
                                        //~ JANUS_LOG(LOG_VERB, " ... parsed RTP packet (ssrc=%u, pt=%u, seq=%u, ts=%u)...\n",
3091
                                                //~ ntohl(rtp->ssrc), rtp->type, ntohs(rtp->seq_number), ntohl(rtp->timestamp));
3092
                                        if(session->media.video_ssrc_peer == 0) {
3093
                                                rtp_header *header = (rtp_header *)buffer;
3094
                                                session->media.video_ssrc_peer = ntohl(header->ssrc);
3095
                                                JANUS_LOG(LOG_VERB, "Got SIP peer video SSRC: %"SCNu32"\n", session->media.video_ssrc_peer);
3096
                                        }
3097
                                        /* Is this SRTP? */
3098
                                        if(session->media.has_srtp_remote) {
3099
                                                int buflen = bytes;
3100
                                                err_status_t res = srtp_unprotect(session->media.video_srtp_in, buffer, &buflen);
3101
                                                if(res != err_status_ok && res != err_status_replay_fail && res != err_status_replay_old) {
3102
                                                        rtp_header *header = (rtp_header *)buffer;
3103
                                                        guint32 timestamp = ntohl(header->timestamp);
3104
                                                        guint16 seq = ntohs(header->seq_number);
3105
                                                        JANUS_LOG(LOG_ERR, "[SIP-%s] Video SRTP unprotect error: %s (len=%d-->%d, ts=%"SCNu32", seq=%"SCNu16")\n",
3106
                                                                session->account.username, janus_sip_get_srtp_error(res), bytes, buflen, timestamp, seq);
3107
                                                        continue;
3108
                                                }
3109
                                                bytes = buflen;
3110
                                        }
3111
                                        /* Save the frame if we're recording */
3112
                                        janus_recorder_save_frame(session->vrc_peer, buffer, bytes);
3113
                                        /* Relay to browser */
3114
                                        gateway->relay_rtp(session->handle, 1, buffer, bytes);
3115
                                        continue;
3116
                                } else if(session->media.video_rtcp_fd != -1 && fds[i].fd == session->media.video_rtcp_fd) {
3117
                                        /* Got something video (RTCP) */
3118
                                        addrlen = sizeof(remote);
3119
                                        bytes = recvfrom(session->media.video_rtcp_fd, buffer, 1500, 0, (struct sockaddr*)&remote, &addrlen);
3120
                                        //~ JANUS_LOG(LOG_VERB, "************************\nGot %d bytes on the video RTCP channel...\n", bytes);
3121
                                        /* Is this SRTCP? */
3122
                                        if(session->media.has_srtp_remote) {
3123
                                                int buflen = bytes;
3124
                                                err_status_t res = srtp_unprotect_rtcp(session->media.video_srtp_in, buffer, &buflen);
3125
                                                if(res != err_status_ok && res != err_status_replay_fail && res != err_status_replay_old) {
3126
                                                        JANUS_LOG(LOG_ERR, "[SIP-%s] Video SRTP unprotect error: %s (len=%d-->%d)\n",
3127
                                                                session->account.username, janus_sip_get_srtp_error(res), bytes, buflen);
3128
                                                        continue;
3129
                                                }
3130
                                                bytes = buflen;
3131
                                        }
3132
                                        /* Relay to browser */
3133
                                        gateway->relay_rtcp(session->handle, 1, buffer, bytes);
3134
                                        continue;
3135
                                }
3136
                        }
3137
                }
3138
        }
3139
        if(session->media.audio_rtp_fd != -1) {
3140
                close(session->media.audio_rtp_fd);
3141
                session->media.audio_rtp_fd = -1;
3142
        }
3143
        if(session->media.audio_rtcp_fd != -1) {
3144
                close(session->media.audio_rtcp_fd);
3145
                session->media.audio_rtcp_fd = -1;
3146
        }
3147
        session->media.local_audio_rtp_port = 0;
3148
        session->media.local_audio_rtcp_port = 0;
3149
        session->media.audio_ssrc = 0;
3150
        if(session->media.video_rtp_fd != -1) {
3151
                close(session->media.video_rtp_fd);
3152
                session->media.video_rtp_fd = -1;
3153
        }
3154
        if(session->media.video_rtcp_fd != -1) {
3155
                close(session->media.video_rtcp_fd);
3156
                session->media.video_rtcp_fd = -1;
3157
        }
3158
        session->media.local_video_rtp_port = 0;
3159
        session->media.local_video_rtcp_port = 0;
3160
        session->media.video_ssrc = 0;
3161
        /* Clean up SRTP stuff, if needed */
3162
        janus_sip_srtp_cleanup(session);
3163
        /* Done */
3164
        JANUS_LOG(LOG_VERB, "Leaving SIP relay thread\n");
3165
        g_thread_unref(g_thread_self());
3166
        return NULL;
3167
}
3168

    
3169

    
3170
/* Sofia Event thread */
3171
gpointer janus_sip_sofia_thread(gpointer user_data) {
3172
        janus_sip_session *session = (janus_sip_session *)user_data;
3173
        if(session == NULL || session->account.username == NULL) {
3174
                g_thread_unref(g_thread_self());
3175
                return NULL;
3176
        }
3177
        JANUS_LOG(LOG_VERB, "Joining sofia loop thread (%s)...\n", session->account.username);
3178
        session->stack = g_malloc0(sizeof(ssip_t));
3179
        session->stack->session = session;
3180
        session->stack->s_nua = NULL;
3181
        session->stack->s_nh_r = NULL;
3182
        session->stack->s_nh_i = NULL;
3183
        session->stack->s_root = su_root_create(session->stack);
3184
        su_home_init(session->stack->s_home);
3185
        JANUS_LOG(LOG_VERB, "Setting up sofia stack (sip:%s@%s)\n", session->account.username, local_ip);
3186
        char sip_url[128];
3187
        char sips_url[128];
3188
        char *ipv6;
3189
        ipv6 = strstr(local_ip, ":");
3190
        g_snprintf(sip_url, sizeof(sip_url), "sip:%s%s%s:*", ipv6 ? "[" : "", local_ip, ipv6 ? "]" : "");
3191
        g_snprintf(sips_url, sizeof(sips_url), "sips:%s%s%s:*", ipv6 ? "[" : "", local_ip, ipv6 ? "]" : "");
3192
        char outbound_options[256] = "use-rport no-validate";
3193
        if(keepalive_interval > 0)
3194
                g_strlcat(outbound_options, " options-keepalive", sizeof(outbound_options));
3195
        if(!behind_nat)
3196
                g_strlcat(outbound_options, " no-natify", sizeof(outbound_options));
3197
        session->stack->s_nua = nua_create(session->stack->s_root,
3198
                                janus_sip_sofia_callback,
3199
                                session,
3200
                                SIPTAG_ALLOW_STR("INVITE, ACK, BYE, CANCEL, OPTIONS"),
3201
                                NUTAG_M_USERNAME(session->account.username),
3202
                                NUTAG_URL(sip_url),
3203
                                TAG_IF(session->account.sips, NUTAG_SIPS_URL(sips_url)),
3204
                                SIPTAG_USER_AGENT_STR(session->account.user_agent ? session->account.user_agent : user_agent),
3205
                                NUTAG_KEEPALIVE(keepalive_interval * 1000),        /* Sofia expects it in milliseconds */
3206
                                NUTAG_OUTBOUND(outbound_options),
3207
                                SIPTAG_SUPPORTED(NULL),
3208
                                TAG_NULL());
3209
        su_root_run(session->stack->s_root);
3210
        /* When we get here, we're done */
3211
        nua_destroy(session->stack->s_nua);
3212
        su_root_destroy(session->stack->s_root);
3213
        session->stack->s_root = NULL;
3214
        su_home_deinit(session->stack->s_home);
3215
        su_home_unref(session->stack->s_home);
3216
        su_deinit();
3217
        if (session->stack) {
3218
                g_free(session->stack);
3219
                session->stack = NULL;
3220
        }
3221
        //~ stop = 1;
3222
        JANUS_LOG(LOG_VERB, "Leaving sofia loop thread...\n");
3223
        g_thread_unref(g_thread_self());
3224
        /* Cleaning up and removing the session is done in a lazy way */
3225
        janus_mutex_lock(&sessions_mutex);
3226
        old_sessions = g_list_append(old_sessions, session);
3227
        janus_mutex_unlock(&sessions_mutex);
3228
        return NULL;
3229
}