Statistics
| Branch: | Revision:

janus-gateway / plugins / janus_sip.c @ 8241c758

History | View | Annotate | Download (144 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
#include <sofia-sip/su_log.h>
65

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

    
76
#ifdef HAVE_SRTP_2
77
#include <srtp2/srtp.h>
78
#include <openssl/rand.h>
79
#include <openssl/err.h>
80
static int srtp_crypto_get_random(uint8_t *key, int len) {
81
        /* libsrtp 2.0 doesn't have crypto_get_random, we use OpenSSL's RAND_* to replace it:
82
         *                 https://wiki.openssl.org/index.php/Random_Numbers */
83
        int rc = RAND_bytes(key, len);
84
        if(rc != 1) {
85
                /* Error generating */
86
                JANUS_LOG(LOG_ERR, "RAND_bytes failes: %s\n", ERR_reason_error_string(ERR_get_error()));
87
                return -1;
88
        }
89
        return 0;
90
}
91
#else
92
#include <srtp/srtp.h>
93
#include <srtp/crypto_kernel.h>
94
#define srtp_err_status_t err_status_t
95
#define srtp_err_status_ok err_status_ok
96
#define srtp_err_status_replay_fail err_status_replay_fail
97
#define srtp_err_status_replay_old err_status_replay_old
98
#define srtp_crypto_policy_set_rtp_default crypto_policy_set_rtp_default
99
#define srtp_crypto_policy_set_rtcp_default crypto_policy_set_rtcp_default
100
#define srtp_crypto_policy_set_aes_cm_128_hmac_sha1_32 crypto_policy_set_aes_cm_128_hmac_sha1_32
101
#define srtp_crypto_policy_set_aes_cm_128_hmac_sha1_80 crypto_policy_set_aes_cm_128_hmac_sha1_80
102
#define srtp_crypto_get_random crypto_get_random
103
#endif
104

    
105

    
106
/* Plugin information */
107
#define JANUS_SIP_VERSION                        6
108
#define JANUS_SIP_VERSION_STRING        "0.0.6"
109
#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."
110
#define JANUS_SIP_NAME                                "JANUS SIP plugin"
111
#define JANUS_SIP_AUTHOR                        "Meetecho s.r.l."
112
#define JANUS_SIP_PACKAGE                        "janus.plugin.sip"
113

    
114
/* Plugin methods */
115
janus_plugin *create(void);
116
int janus_sip_init(janus_callbacks *callback, const char *config_path);
117
void janus_sip_destroy(void);
118
int janus_sip_get_api_compatibility(void);
119
int janus_sip_get_version(void);
120
const char *janus_sip_get_version_string(void);
121
const char *janus_sip_get_description(void);
122
const char *janus_sip_get_name(void);
123
const char *janus_sip_get_author(void);
124
const char *janus_sip_get_package(void);
125
void janus_sip_create_session(janus_plugin_session *handle, int *error);
126
struct janus_plugin_result *janus_sip_handle_message(janus_plugin_session *handle, char *transaction, json_t *message, json_t *jsep);
127
void janus_sip_setup_media(janus_plugin_session *handle);
128
void janus_sip_incoming_rtp(janus_plugin_session *handle, int video, char *buf, int len);
129
void janus_sip_incoming_rtcp(janus_plugin_session *handle, int video, char *buf, int len);
130
void janus_sip_hangup_media(janus_plugin_session *handle);
131
void janus_sip_destroy_session(janus_plugin_session *handle, int *error);
132
json_t *janus_sip_query_session(janus_plugin_session *handle);
133

    
134
/* Plugin setup */
135
static janus_plugin janus_sip_plugin =
136
        JANUS_PLUGIN_INIT (
137
                .init = janus_sip_init,
138
                .destroy = janus_sip_destroy,
139

    
140
                .get_api_compatibility = janus_sip_get_api_compatibility,
141
                .get_version = janus_sip_get_version,
142
                .get_version_string = janus_sip_get_version_string,
143
                .get_description = janus_sip_get_description,
144
                .get_name = janus_sip_get_name,
145
                .get_author = janus_sip_get_author,
146
                .get_package = janus_sip_get_package,
147

    
148
                .create_session = janus_sip_create_session,
149
                .handle_message = janus_sip_handle_message,
150
                .setup_media = janus_sip_setup_media,
151
                .incoming_rtp = janus_sip_incoming_rtp,
152
                .incoming_rtcp = janus_sip_incoming_rtcp,
153
                .hangup_media = janus_sip_hangup_media,
154
                .destroy_session = janus_sip_destroy_session,
155
                .query_session = janus_sip_query_session,
156
        );
157

    
158
/* Plugin creator */
159
janus_plugin *create(void) {
160
        JANUS_LOG(LOG_VERB, "%s created!\n", JANUS_SIP_NAME);
161
        return &janus_sip_plugin;
162
}
163

    
164
/* Parameter validation */
165
static struct janus_json_parameter request_parameters[] = {
166
        {"request", JSON_STRING, JANUS_JSON_PARAM_REQUIRED}
167
};
168
static struct janus_json_parameter register_parameters[] = {
169
        {"type", JSON_STRING, 0},
170
        {"send_register", JANUS_JSON_BOOL, 0},
171
        {"sips", JANUS_JSON_BOOL, 0},
172
        {"username", JSON_STRING, 0},
173
        {"secret", JSON_STRING, 0},
174
        {"ha1_secret", JSON_STRING, 0},
175
        {"authuser", JSON_STRING, 0}
176
};
177
static struct janus_json_parameter proxy_parameters[] = {
178
        {"proxy", JSON_STRING, 0}
179
};
180
static struct janus_json_parameter call_parameters[] = {
181
        {"uri", JSON_STRING, JANUS_JSON_PARAM_REQUIRED},
182
        {"autoack", JANUS_JSON_BOOL, 0},
183
        {"headers", JSON_OBJECT, 0},
184
        {"srtp", JSON_STRING, 0}
185
};
186
static struct janus_json_parameter accept_parameters[] = {
187
        {"srtp", JSON_STRING, 0}
188
};
189
static struct janus_json_parameter recording_parameters[] = {
190
        {"action", JSON_STRING, JANUS_JSON_PARAM_REQUIRED},
191
        {"audio", JANUS_JSON_BOOL, 0},
192
        {"video", JANUS_JSON_BOOL, 0},
193
        {"peer_audio", JANUS_JSON_BOOL, 0},
194
        {"peer_video", JANUS_JSON_BOOL, 0},
195
        {"filename", JSON_STRING, 0}
196
};
197
static struct janus_json_parameter dtmf_info_parameters[] = {
198
        {"digit", JSON_STRING, JANUS_JSON_PARAM_REQUIRED},
199
        {"duration", JSON_INTEGER, JANUS_JSON_PARAM_POSITIVE}
200
};
201

    
202
/* Useful stuff */
203
static volatile gint initialized = 0, stopping = 0;
204
static gboolean notify_events = TRUE;
205
static janus_callbacks *gateway = NULL;
206

    
207
static char local_ip[INET6_ADDRSTRLEN];
208
static int keepalive_interval = 120;
209
static gboolean behind_nat = FALSE;
210
static char *user_agent;
211
#define JANUS_DEFAULT_REGISTER_TTL        3600
212
static int register_ttl = JANUS_DEFAULT_REGISTER_TTL;
213

    
214
static GThread *handler_thread;
215
static GThread *watchdog;
216
static void *janus_sip_handler(void *data);
217

    
218
typedef struct janus_sip_message {
219
        janus_plugin_session *handle;
220
        char *transaction;
221
        json_t *message;
222
        json_t *jsep;
223
} janus_sip_message;
224
static GAsyncQueue *messages = NULL;
225
static janus_sip_message exit_message;
226

    
227
static void janus_sip_message_free(janus_sip_message *msg) {
228
        if(!msg || msg == &exit_message)
229
                return;
230

    
231
        msg->handle = NULL;
232

    
233
        g_free(msg->transaction);
234
        msg->transaction = NULL;
235
        if(msg->message)
236
                json_decref(msg->message);
237
        msg->message = NULL;
238
        if(msg->jsep)
239
                json_decref(msg->jsep);
240
        msg->jsep = NULL;
241

    
242
        g_free(msg);
243
}
244

    
245

    
246
typedef enum {
247
        janus_sip_registration_status_disabled = -2,
248
        janus_sip_registration_status_failed = -1,
249
        janus_sip_registration_status_unregistered = 0,
250
        janus_sip_registration_status_registering,
251
        janus_sip_registration_status_registered,
252
        janus_sip_registration_status_unregistering,
253
} janus_sip_registration_status;
254

    
255
static const char *janus_sip_registration_status_string(janus_sip_registration_status status) {
256
        switch(status) {
257
                case janus_sip_registration_status_disabled:
258
                        return "disabled";
259
                case janus_sip_registration_status_failed:
260
                        return "failed";
261
                case janus_sip_registration_status_unregistered:
262
                        return "unregistered";
263
                case janus_sip_registration_status_registering:
264
                        return "registering";
265
                case janus_sip_registration_status_registered:
266
                        return "registered";
267
                case janus_sip_registration_status_unregistering:
268
                        return "unregistering";
269
                default:
270
                        return "unknown";
271
        }
272
}
273

    
274

    
275
typedef enum {
276
        janus_sip_call_status_idle = 0,
277
        janus_sip_call_status_inviting,
278
        janus_sip_call_status_invited,
279
        janus_sip_call_status_incall,
280
        janus_sip_call_status_closing,
281
} janus_sip_call_status;
282

    
283
static const char *janus_sip_call_status_string(janus_sip_call_status status) {
284
        switch(status) {
285
                case janus_sip_call_status_idle:
286
                        return "idle";
287
                case janus_sip_call_status_inviting:
288
                        return "inviting";
289
                case janus_sip_call_status_invited:
290
                        return "invited";
291
                case janus_sip_call_status_incall:
292
                        return "incall";
293
                case janus_sip_call_status_closing:
294
                        return "closing";
295
                default:
296
                        return "unknown";
297
        }
298
}
299

    
300

    
301
/* Sofia stuff */
302
typedef struct ssip_s ssip_t;
303
typedef struct ssip_oper_s ssip_oper_t;
304

    
305
typedef enum {
306
        janus_sip_secret_type_plaintext = 1,
307
        janus_sip_secret_type_hashed = 2,
308
        janus_sip_secret_type_unknown
309
} janus_sip_secret_type;
310

    
311
typedef struct janus_sip_account {
312
        char *identity;
313
        char *user_agent;                /* Used to override the general UA string */
314
        gboolean sips;
315
        char *username;
316
        char *display_name;                /* Used for outgoing calls in the From header */
317
        char *authuser;                        /**< username to use for authentication */
318
        char *secret;
319
        janus_sip_secret_type secret_type;
320
        int sip_port;
321
        char *proxy;
322
        janus_sip_registration_status registration_status;
323
} janus_sip_account;
324

    
325
typedef struct janus_sip_rtp_context {
326
        /* Needed to fix seq and ts in case of re-INVITEs/UPDATEs that result in a RTP stream */
327
        uint32_t a_last_ssrc, a_last_ts, a_base_ts, a_base_ts_prev,
328
                        v_last_ssrc, v_last_ts, v_base_ts, v_base_ts_prev;
329
        uint16_t a_last_seq, a_base_seq, a_base_seq_prev,
330
                        v_last_seq, v_base_seq, v_base_seq_prev;
331
} janus_sip_rtp_context;
332

    
333
typedef struct janus_sip_media {
334
        char *remote_ip;
335
        int ready:1;
336
        gboolean autoack;
337
        gboolean require_srtp, has_srtp_local, has_srtp_remote;
338
        int has_audio:1;
339
        int audio_rtp_fd, audio_rtcp_fd;
340
        int local_audio_rtp_port, remote_audio_rtp_port;
341
        int local_audio_rtcp_port, remote_audio_rtcp_port;
342
        guint32 audio_ssrc, audio_ssrc_peer;
343
        int audio_pt;
344
        const char *audio_pt_name;
345
        srtp_t audio_srtp_in, audio_srtp_out;
346
        srtp_policy_t audio_remote_policy, audio_local_policy;
347
        int audio_srtp_suite_in, audio_srtp_suite_out;
348
        gboolean audio_send;
349
        int has_video:1;
350
        int video_rtp_fd, video_rtcp_fd;
351
        int local_video_rtp_port, remote_video_rtp_port;
352
        int local_video_rtcp_port, remote_video_rtcp_port;
353
        guint32 video_ssrc, video_ssrc_peer;
354
        int video_pt;
355
        const char *video_pt_name;
356
        srtp_t video_srtp_in, video_srtp_out;
357
        srtp_policy_t video_remote_policy, video_local_policy;
358
        int video_srtp_suite_in, video_srtp_suite_out;
359
        gboolean video_send;
360
        janus_sip_rtp_context context;
361
        int pipefd[2];
362
        gboolean updated;
363
} janus_sip_media;
364

    
365
typedef struct janus_sip_session {
366
        janus_plugin_session *handle;
367
        ssip_t *stack;
368
        janus_sip_account account;
369
        janus_sip_call_status status;
370
        janus_sip_media media;
371
        char *transaction;
372
        char *callee;
373
        char *callid;
374
        janus_sdp *sdp;                                /* The SDP this user sent */
375
        janus_recorder *arc;                /* The Janus recorder instance for this user's audio, if enabled */
376
        janus_recorder *arc_peer;        /* The Janus recorder instance for the peer's audio, if enabled */
377
        janus_recorder *vrc;                /* The Janus recorder instance for this user's video, if enabled */
378
        janus_recorder *vrc_peer;        /* The Janus recorder instance for the peer's video, if enabled */
379
        janus_mutex rec_mutex;                /* Mutex to protect the recorders from race conditions */
380
        volatile gint hangingup;
381
        gint64 destroyed;        /* Time at which this session was marked as destroyed */
382
        janus_mutex mutex;
383
} janus_sip_session;
384
static GHashTable *sessions;
385
static GList *old_sessions;
386
static GHashTable *identities;
387
static GHashTable *callids;
388
static janus_mutex sessions_mutex;
389

    
390

    
391
#undef SU_ROOT_MAGIC_T
392
#define SU_ROOT_MAGIC_T        ssip_t
393
#undef NUA_MAGIC_T
394
#define NUA_MAGIC_T                ssip_t
395
#undef NUA_HMAGIC_T
396
#define NUA_HMAGIC_T        ssip_oper_t
397

    
398
struct ssip_s {
399
        su_home_t s_home[1];
400
        su_root_t *s_root;
401
        nua_t *s_nua;
402
        nua_handle_t *s_nh_r, *s_nh_i;
403
        janus_sip_session *session;
404
};
405

    
406

    
407
/* SRTP stuff (in case we need SDES) */
408
#define SRTP_MASTER_KEY_LENGTH        16
409
#define SRTP_MASTER_SALT_LENGTH        14
410
#define SRTP_MASTER_LENGTH (SRTP_MASTER_KEY_LENGTH + SRTP_MASTER_SALT_LENGTH)
411
static const char *janus_sip_srtp_error[] =
412
{
413
        "srtp_err_status_ok",
414
        "srtp_err_status_fail",
415
        "srtp_err_status_bad_param",
416
        "srtp_err_status_alloc_fail",
417
        "srtp_err_status_dealloc_fail",
418
        "srtp_err_status_init_fail",
419
        "srtp_err_status_terminus",
420
        "srtp_err_status_auth_fail",
421
        "srtp_err_status_cipher_fail",
422
        "srtp_err_status_replay_fail",
423
        "srtp_err_status_replay_old",
424
        "srtp_err_status_algo_fail",
425
        "srtp_err_status_no_such_op",
426
        "srtp_err_status_no_ctx",
427
        "srtp_err_status_cant_check",
428
        "srtp_err_status_key_expired",
429
        "srtp_err_status_socket_err",
430
        "srtp_err_status_signal_err",
431
        "srtp_err_status_nonce_bad",
432
        "srtp_err_status_read_fail",
433
        "srtp_err_status_write_fail",
434
        "srtp_err_status_parse_err",
435
        "srtp_err_status_encode_err",
436
        "srtp_err_status_semaphore_err",
437
        "srtp_err_status_pfkey_err",
438
};
439
static const gchar *janus_sip_get_srtp_error(int error) {
440
        if(error < 0 || error > 24)
441
                return NULL;
442
        return janus_sip_srtp_error[error];
443
}
444
static int janus_sip_srtp_set_local(janus_sip_session *session, gboolean video, char **crypto) {
445
        if(session == NULL)
446
                return -1;
447
        /* Generate key/salt */
448
        uint8_t *key = g_malloc0(SRTP_MASTER_LENGTH);
449
        srtp_crypto_get_random(key, SRTP_MASTER_LENGTH);
450
        /* Set SRTP policies */
451
        srtp_policy_t *policy = video ? &session->media.video_local_policy : &session->media.audio_local_policy;
452
        srtp_crypto_policy_set_rtp_default(&(policy->rtp));
453
        srtp_crypto_policy_set_rtcp_default(&(policy->rtcp));
454
        policy->ssrc.type = ssrc_any_inbound;
455
        policy->key = key;
456
        policy->next = NULL;
457
        /* Create SRTP context */
458
        srtp_err_status_t res = srtp_create(video ? &session->media.video_srtp_out : &session->media.audio_srtp_out, policy);
459
        if(res != srtp_err_status_ok) {
460
                /* Something went wrong... */
461
                JANUS_LOG(LOG_ERR, "Oops, error creating outbound SRTP session: %d (%s)\n", res, janus_sip_get_srtp_error(res));
462
                g_free(key);
463
                policy->key = NULL;
464
                return -2;
465
        }
466
        /* Base64 encode the salt */
467
        *crypto = g_base64_encode(key, SRTP_MASTER_LENGTH);
468
        if((video && session->media.video_srtp_out) || (!video && session->media.audio_srtp_out)) {
469
                JANUS_LOG(LOG_VERB, "%s outbound SRTP session created\n", video ? "Video" : "Audio");
470
        }
471
        return 0;
472
}
473
static int janus_sip_srtp_set_remote(janus_sip_session *session, gboolean video, const char *crypto, int suite) {
474
        if(session == NULL || crypto == NULL)
475
                return -1;
476
        /* Base64 decode the crypto string and set it as the remote SRTP context */
477
        gsize len = 0;
478
        guchar *decoded = g_base64_decode(crypto, &len);
479
        if(len < SRTP_MASTER_LENGTH) {
480
                /* FIXME Can this happen? */
481
                g_free(decoded);
482
                return -2;
483
        }
484
        /* Set SRTP policies */
485
        srtp_policy_t *policy = video ? &session->media.video_remote_policy : &session->media.audio_remote_policy;
486
        srtp_crypto_policy_set_rtp_default(&(policy->rtp));
487
        srtp_crypto_policy_set_rtcp_default(&(policy->rtcp));
488
        if(suite == 32) {
489
                srtp_crypto_policy_set_aes_cm_128_hmac_sha1_32(&(policy->rtp));
490
                srtp_crypto_policy_set_aes_cm_128_hmac_sha1_32(&(policy->rtcp));
491
        } else if(suite == 80) {
492
                srtp_crypto_policy_set_aes_cm_128_hmac_sha1_80(&(policy->rtp));
493
                srtp_crypto_policy_set_aes_cm_128_hmac_sha1_80(&(policy->rtcp));
494
        }
495
        policy->ssrc.type = ssrc_any_inbound;
496
        policy->key = decoded;
497
        policy->next = NULL;
498
        /* Create SRTP context */
499
        srtp_err_status_t res = srtp_create(video ? &session->media.video_srtp_in : &session->media.audio_srtp_in, policy);
500
        if(res != srtp_err_status_ok) {
501
                /* Something went wrong... */
502
                JANUS_LOG(LOG_ERR, "Oops, error creating inbound SRTP session: %d (%s)\n", res, janus_sip_get_srtp_error(res));
503
                g_free(decoded);
504
                policy->key = NULL;
505
                return -2;
506
        }
507
        if((video && session->media.video_srtp_in) || (!video && session->media.audio_srtp_in)) {
508
                JANUS_LOG(LOG_VERB, "%s inbound SRTP session created\n", video ? "Video" : "Audio");
509
        }
510
        return 0;
511
}
512
static void janus_sip_srtp_cleanup(janus_sip_session *session) {
513
        if(session == NULL)
514
                return;
515
        session->media.autoack = TRUE;
516
        session->media.require_srtp = FALSE;
517
        session->media.has_srtp_local = FALSE;
518
        session->media.has_srtp_remote = FALSE;
519
        /* Audio */
520
        if(session->media.audio_srtp_out)
521
                srtp_dealloc(session->media.audio_srtp_out);
522
        session->media.audio_srtp_out = NULL;
523
        g_free(session->media.audio_local_policy.key);
524
        session->media.audio_local_policy.key = NULL;
525
        session->media.audio_srtp_suite_out = 0;
526
        if(session->media.audio_srtp_in)
527
                srtp_dealloc(session->media.audio_srtp_in);
528
        session->media.audio_srtp_in = NULL;
529
        g_free(session->media.audio_remote_policy.key);
530
        session->media.audio_remote_policy.key = NULL;
531
        session->media.audio_srtp_suite_in = 0;
532
        /* Video */
533
        if(session->media.video_srtp_out)
534
                srtp_dealloc(session->media.video_srtp_out);
535
        session->media.video_srtp_out = NULL;
536
        g_free(session->media.video_local_policy.key);
537
        session->media.video_local_policy.key = NULL;
538
        session->media.video_srtp_suite_out = 0;
539
        if(session->media.video_srtp_in)
540
                srtp_dealloc(session->media.video_srtp_in);
541
        session->media.video_srtp_in = NULL;
542
        g_free(session->media.video_remote_policy.key);
543
        session->media.video_remote_policy.key = NULL;
544
        session->media.video_srtp_suite_in = 0;
545
}
546

    
547

    
548
/* Sofia Event thread */
549
gpointer janus_sip_sofia_thread(gpointer user_data);
550
/* Sofia callbacks */
551
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[]);
552
/* SDP parsing and manipulation */
553
void janus_sip_sdp_process(janus_sip_session *session, janus_sdp *sdp, gboolean answer, gboolean update, gboolean *changed);
554
char *janus_sip_sdp_manipulate(janus_sip_session *session, janus_sdp *sdp, gboolean answer);
555
/* Media */
556
static int janus_sip_allocate_local_ports(janus_sip_session *session);
557
static void *janus_sip_relay_thread(void *data);
558

    
559

    
560
/* URI parsing utilies */
561

    
562
#define JANUS_SIP_URI_MAXLEN        1024
563
typedef struct {
564
        char data[JANUS_SIP_URI_MAXLEN];
565
        url_t url[1];
566
} janus_sip_uri_t;
567

    
568
/* Parses a SIP URI (SIPS is not supported), returns 0 on success, -1 otherwise */
569
static int janus_sip_parse_uri(janus_sip_uri_t *sip_uri, const char *data) {
570
        g_strlcpy(sip_uri->data, data, JANUS_SIP_URI_MAXLEN);
571
        if (url_d(sip_uri->url, sip_uri->data) < 0 || sip_uri->url->url_type != url_sip)
572
                return -1;
573
        return 0;
574
}
575

    
576
/* Similar to the above function, but it also accepts SIPS URIs */
577
static int janus_sip_parse_proxy_uri(janus_sip_uri_t *sip_uri, const char *data) {
578
        g_strlcpy(sip_uri->data, data, JANUS_SIP_URI_MAXLEN);
579
        if (url_d(sip_uri->url, sip_uri->data) < 0 || (sip_uri->url->url_type != url_sip && sip_uri->url->url_type != url_sips))
580
                return -1;
581
        return 0;
582
}
583

    
584
/* Error codes */
585
#define JANUS_SIP_ERROR_UNKNOWN_ERROR                499
586
#define JANUS_SIP_ERROR_NO_MESSAGE                        440
587
#define JANUS_SIP_ERROR_INVALID_JSON                441
588
#define JANUS_SIP_ERROR_INVALID_REQUEST                442
589
#define JANUS_SIP_ERROR_MISSING_ELEMENT                443
590
#define JANUS_SIP_ERROR_INVALID_ELEMENT                444
591
#define JANUS_SIP_ERROR_ALREADY_REGISTERED        445
592
#define JANUS_SIP_ERROR_INVALID_ADDRESS                446
593
#define JANUS_SIP_ERROR_WRONG_STATE                        447
594
#define JANUS_SIP_ERROR_MISSING_SDP                        448
595
#define JANUS_SIP_ERROR_LIBSOFIA_ERROR                449
596
#define JANUS_SIP_ERROR_IO_ERROR                        450
597
#define JANUS_SIP_ERROR_RECORDING_ERROR                451
598
#define JANUS_SIP_ERROR_TOO_STRICT                        452
599

    
600

    
601
/* SIP watchdog/garbage collector (sort of) */
602
void *janus_sip_watchdog(void *data);
603
void *janus_sip_watchdog(void *data) {
604
        JANUS_LOG(LOG_INFO, "SIP watchdog started\n");
605
        gint64 now = 0;
606
        while(g_atomic_int_get(&initialized) && !g_atomic_int_get(&stopping)) {
607
                janus_mutex_lock(&sessions_mutex);
608
                /* Iterate on all the sessions */
609
                now = janus_get_monotonic_time();
610
                if(old_sessions != NULL) {
611
                        GList *sl = old_sessions;
612
                        JANUS_LOG(LOG_HUGE, "Checking %d old SIP sessions...\n", g_list_length(old_sessions));
613
                        while(sl) {
614
                                janus_sip_session *session = (janus_sip_session *)sl->data;
615
                                if(!session) {
616
                                        sl = sl->next;
617
                                        continue;
618
                                }
619
                                if (now-session->destroyed >= 5*G_USEC_PER_SEC) {
620
                                        /* We're lazy and actually get rid of the stuff only after a few seconds */
621
                                        JANUS_LOG(LOG_VERB, "Freeing old SIP session\n");
622
                                        GList *rm = sl->next;
623
                                        old_sessions = g_list_delete_link(old_sessions, sl);
624
                                        sl = rm;
625
                                        if (session->account.identity) {
626
                                            g_hash_table_remove(identities, session->account.identity);
627
                                            g_free(session->account.identity);
628
                                            session->account.identity = NULL;
629
                                        }
630
                                        session->account.sips = TRUE;
631
                                        if (session->account.proxy) {
632
                                            g_free(session->account.proxy);
633
                                            session->account.proxy = NULL;
634
                                        }
635
                                        if (session->account.secret) {
636
                                            g_free(session->account.secret);
637
                                            session->account.secret = NULL;
638
                                        }
639
                                        if (session->account.username) {
640
                                            g_free(session->account.username);
641
                                            session->account.username = NULL;
642
                                        }
643
                                        if (session->account.display_name) {
644
                                            g_free(session->account.display_name);
645
                                            session->account.display_name = NULL;
646
                                        }
647
                                        if (session->account.user_agent) {
648
                                            g_free(session->account.user_agent);
649
                                            session->account.user_agent = NULL;
650
                                        }
651
                                        if (session->account.authuser) {
652
                                            g_free(session->account.authuser);
653
                                            session->account.authuser = NULL;
654
                                        }
655
                                        if (session->callee) {
656
                                            g_free(session->callee);
657
                                            session->callee = NULL;
658
                                        }
659
                                        if (session->callid) {
660
                                            g_hash_table_remove(callids, session->callid);
661
                                            g_free(session->callid);
662
                                            session->callid = NULL;
663
                                        }
664
                                        if (session->sdp) {
665
                                            janus_sdp_free(session->sdp);
666
                                            session->sdp = NULL;
667
                                        }
668
                                        if (session->transaction) {
669
                                            g_free(session->transaction);
670
                                            session->transaction = NULL;
671
                                        }
672
                                        if (session->media.remote_ip) {
673
                                            g_free(session->media.remote_ip);
674
                                            session->media.remote_ip = NULL;
675
                                        }
676
                                        janus_sip_srtp_cleanup(session);
677
                                        session->handle = NULL;
678
                                        g_free(session);
679
                                        session = NULL;
680
                                        continue;
681
                                }
682
                                sl = sl->next;
683
                        }
684
                }
685
                janus_mutex_unlock(&sessions_mutex);
686
                g_usleep(500000);
687
        }
688
        JANUS_LOG(LOG_INFO, "SIP watchdog stopped\n");
689
        return NULL;
690
}
691

    
692

    
693
static void janus_sip_detect_local_ip(char *buf, size_t buflen) {
694
        JANUS_LOG(LOG_VERB, "Autodetecting local IP...\n");
695

    
696
        struct sockaddr_in addr;
697
        socklen_t len;
698
        int fd = socket(AF_INET, SOCK_DGRAM, 0);
699
        if (fd == -1)
700
                goto error;
701
        addr.sin_family = AF_INET;
702
        addr.sin_port = htons(1);
703
        inet_pton(AF_INET, "1.2.3.4", &addr.sin_addr.s_addr);
704
        if (connect(fd, (const struct sockaddr*) &addr, sizeof(addr)) < 0)
705
                goto error;
706
        len = sizeof(addr);
707
        if (getsockname(fd, (struct sockaddr*) &addr, &len) < 0)
708
                goto error;
709
        if (getnameinfo((const struct sockaddr*) &addr, sizeof(addr),
710
                        buf, buflen,
711
                        NULL, 0, NI_NUMERICHOST) != 0)
712
                goto error;
713
        close(fd);
714
        return;
715

    
716
error:
717
        if (fd != -1)
718
                close(fd);
719
        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");
720
        g_strlcpy(buf, "127.0.0.1", buflen);
721
}
722

    
723

    
724
/* Random string helper (for call-ids) */
725
static char charset[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
726
static void janus_sip_random_string(int length, char *buffer) {
727
        if(length > 0 && buffer) {
728
                int l = (int)(sizeof(charset)-1);
729
                int i=0;
730
                for(i=0; i<length; i++) {
731
                        int key = rand() % l;
732
                        buffer[i] = charset[key];
733
                }
734
                buffer[length-1] = '\0';
735
        }
736
}
737

    
738

    
739
/* Sofia SIP logger function: when the Event Handlers mechanism is enabled,
740
 * we use this to intercept SIP messages sent by the stack (received
741
 * messages are more easily recoverable in janus_sip_sofia_callback) */
742
char sofia_log[2048];
743
char call_id[255];
744
gboolean skip = FALSE, started = FALSE, append = FALSE;
745
static void janus_sip_sofia_logger(void *stream, char const *fmt, va_list ap) {
746
        if(!fmt)
747
                return;
748
        char line[255];
749
        g_vsnprintf(line, sizeof(line), fmt, ap);
750
        if(skip) {
751
                /* This is a message we're not interested in: just check when it ends */
752
                if(line[3] == '-') {
753
                        skip = FALSE;
754
                        append = FALSE;
755
                }
756
                return;
757
        }
758
        if(append) {
759
                /* We're copying a message in our buffer: check if this is the end */
760
                if(line[3] == '-') {
761
                        if(!started) {
762
                                /* Ok, start appending from now on */
763
                                started = TRUE;
764
                                sofia_log[0] = '\0';
765
                                call_id[0] = '\0';
766
                        } else {
767
                                /* Message ended, handle it */
768
                                skip = FALSE;
769
                                append = FALSE;
770
                                /* Look for the session this message belongs to */
771
                                janus_sip_session *session = NULL;
772
                                if(strlen(call_id))
773
                                        session = g_hash_table_lookup(callids, call_id);
774
                                if(!session) {
775
                                        /* Couldn't find any SIP session with that Call-ID, check the request */
776
                                        if(strstr(sofia_log, "REGISTER") == sofia_log || strstr(sofia_log, "SIP/2.0 ") == sofia_log) {
777
                                                /* FIXME This is a REGISTER or a response code:
778
                                                 * check the To header and get the identity from there */
779
                                                char *from = strstr(sofia_log, "To: ");
780
                                                if(from) {
781
                                                        from = from+4;
782
                                                        char *start = strstr(from, "<");
783
                                                        if(start) {
784
                                                                start++;
785
                                                                char *end = strstr(from, ">");
786
                                                                if(end) {
787
                                                                        *end = '\0';
788
                                                                        g_snprintf(call_id, sizeof(call_id), "%s", start);
789
                                                                        *end = '>';
790
                                                                        session = g_hash_table_lookup(identities, call_id);
791
                                                                }
792
                                                        }
793
                                                }
794
                                        }
795
                                }
796
                                if(session) {
797
                                        /* Notify event handlers about the content of the whole outgoing SIP message */
798
                                        json_t *info = json_object();
799
                                        json_object_set_new(info, "event", json_string("sip-out"));
800
                                        json_object_set_new(info, "sip", json_string(sofia_log));
801
                                        gateway->notify_event(&janus_sip_plugin, session->handle, info);
802
                                } else {
803
                                        JANUS_LOG(LOG_WARN, "Couldn't find a session associated to this message, dropping it...\n%s", sofia_log);
804
                                }
805
                                /* Done, reset the buffers */
806
                                sofia_log[0] = '\0';
807
                                call_id[0] = '\0';
808
                        }
809
                        return;
810
                }
811
                if(strlen(line) == 1) {
812
                        /* Append a carriage and return */
813
                        g_strlcat(sofia_log, "\r\n", sizeof(sofia_log));
814
                } else {
815
                        /* If this is an OPTIONS, we don't care: drop it */
816
                        char *header = &line[3];
817
                        if(strstr(header, "OPTIONS") == header) {
818
                                skip = TRUE;
819
                                return;
820
                        }
821
                        /* Is this a Call-ID header? Keep note of it */
822
                        if(strstr(header, "Call-ID") == header) {
823
                                g_snprintf(call_id, sizeof(call_id), "%s", header+9);
824
                        }
825
                        /* Append the line to our buffer, skipping the indent */
826
                        g_strlcat(sofia_log, &line[3], sizeof(sofia_log));
827
                }
828
                return;
829
        }
830
        /* Still waiting to decide if this is a message we need */
831
        if(line[0] == 's' && line[1] == 'e' && line[2] == 'n' && line[3] == 'd' && line[4] == ' ') {
832
                /* An outgoing message is going to be logged, prepare for that */
833
                skip = FALSE;
834
                started = FALSE;
835
                append = TRUE;
836
                int length = atoi(&line[5]);
837
                JANUS_LOG(LOG_HUGE, "Intercepting message (%d bytes)\n", length);
838
                if(strstr(line, "-----"))
839
                        started = TRUE;
840
        }
841
}
842

    
843

    
844
/* Plugin implementation */
845
int janus_sip_init(janus_callbacks *callback, const char *config_path) {
846
        if(g_atomic_int_get(&stopping)) {
847
                /* Still stopping from before */
848
                return -1;
849
        }
850
        if(callback == NULL || config_path == NULL) {
851
                /* Invalid arguments */
852
                return -1;
853
        }
854

    
855
        /* Read configuration */
856
        char filename[255];
857
        g_snprintf(filename, 255, "%s/%s.cfg", config_path, JANUS_SIP_PACKAGE);
858
        JANUS_LOG(LOG_VERB, "Configuration file: %s\n", filename);
859
        janus_config *config = janus_config_parse(filename);
860
        if(config != NULL) {
861
                janus_config_print(config);
862

    
863
                gboolean local_ip_set = FALSE;
864
                janus_config_item *item = janus_config_get_item_drilldown(config, "general", "local_ip");
865
                if(item && item->value) {
866
                        int family;
867
                        if (!janus_is_ip_valid(item->value, &family)) {
868
                                JANUS_LOG(LOG_WARN, "Invalid local IP specified: %s, guessing the default...\n", item->value);
869
                        } else {
870
                                /* Verify that we can actually bind to that address */
871
                                int fd = socket(family, SOCK_DGRAM, 0);
872
                                if (fd == -1) {
873
                                        JANUS_LOG(LOG_WARN, "Error creating test socket, falling back to detecting IP address...\n");
874
                                } else {
875
                                        int r;
876
                                        struct sockaddr_storage ss;
877
                                        socklen_t addrlen;
878
                                        memset(&ss, 0, sizeof(ss));
879
                                        if (family == AF_INET) {
880
                                                struct sockaddr_in *addr4 = (struct sockaddr_in*)&ss;
881
                                                addr4->sin_family = AF_INET;
882
                                                addr4->sin_port = 0;
883
                                                inet_pton(AF_INET, item->value, &(addr4->sin_addr.s_addr));
884
                                                addrlen = sizeof(struct sockaddr_in);
885
                                        } else {
886
                                                struct sockaddr_in6 *addr6 = (struct sockaddr_in6*)&ss;
887
                                                addr6->sin6_family = AF_INET6;
888
                                                addr6->sin6_port = 0;
889
                                                inet_pton(AF_INET6, item->value, &(addr6->sin6_addr.s6_addr));
890
                                                addrlen = sizeof(struct sockaddr_in6);
891
                                        }
892
                                        r = bind(fd, (const struct sockaddr*)&ss, addrlen);
893
                                        close(fd);
894
                                        if (r < 0) {
895
                                                JANUS_LOG(LOG_WARN, "Error setting local IP address to %s, falling back to detecting IP address...\n", item->value);
896
                                        } else {
897
                                                g_strlcpy(local_ip, item->value, sizeof(local_ip));
898
                                                local_ip_set = TRUE;
899
                                        }
900
                                }
901
                        }
902
                }
903
                if (!local_ip_set)
904
                        janus_sip_detect_local_ip(local_ip, sizeof(local_ip));
905
                JANUS_LOG(LOG_VERB, "Local IP set to %s\n", local_ip);
906

    
907
                item = janus_config_get_item_drilldown(config, "general", "keepalive_interval");
908
                if(item && item->value)
909
                        keepalive_interval = atoi(item->value);
910
                JANUS_LOG(LOG_VERB, "SIP keep-alive interval set to %d seconds\n", keepalive_interval);
911

    
912
                item = janus_config_get_item_drilldown(config, "general", "register_ttl");
913
                if(item && item->value)
914
                        register_ttl = atoi(item->value);
915
                JANUS_LOG(LOG_VERB, "SIP registration TTL set to %d seconds\n", register_ttl);
916

    
917
                item = janus_config_get_item_drilldown(config, "general", "behind_nat");
918
                if(item && item->value)
919
                        behind_nat = janus_is_true(item->value);
920

    
921
                item = janus_config_get_item_drilldown(config, "general", "user_agent");
922
                if(item && item->value)
923
                        user_agent = g_strdup(item->value);
924
                else
925
                        user_agent = g_strdup("Janus WebRTC Gateway SIP Plugin "JANUS_SIP_VERSION_STRING);
926
                JANUS_LOG(LOG_VERB, "SIP User-Agent set to %s\n", user_agent);
927

    
928
                item = janus_config_get_item_drilldown(config, "general", "events");
929
                if(item != NULL && item->value != NULL)
930
                        notify_events = janus_is_true(item->value);
931
                if(!notify_events && callback->events_is_enabled()) {
932
                        JANUS_LOG(LOG_WARN, "Notification of events to handlers disabled for %s\n", JANUS_SIP_NAME);
933
                }
934

    
935
                janus_config_destroy(config);
936
        }
937
        config = NULL;
938

    
939
#ifdef HAVE_SRTP_2
940
        /* Init randomizer (for randum numbers in SRTP) */
941
        RAND_poll();
942
#endif
943

    
944
        /* Setup sofia */
945
        su_init();
946
        if(callback->events_is_enabled()) {
947
                /* Enable the transport logging, as we want to have access to the SIP messages */
948
                setenv("TPORT_LOG", "1", 1);
949
                su_log_redirect(NULL, janus_sip_sofia_logger, NULL);
950
        }
951

    
952
        sessions = g_hash_table_new(NULL, NULL);
953
        callids = g_hash_table_new(g_str_hash, g_str_equal);
954
        identities = g_hash_table_new(g_str_hash, g_str_equal);
955
        janus_mutex_init(&sessions_mutex);
956
        messages = g_async_queue_new_full((GDestroyNotify) janus_sip_message_free);
957
        /* This is the callback we'll need to invoke to contact the gateway */
958
        gateway = callback;
959

    
960
        g_atomic_int_set(&initialized, 1);
961

    
962
        GError *error = NULL;
963
        /* Start the sessions watchdog */
964
        watchdog = g_thread_try_new("sip watchdog", &janus_sip_watchdog, NULL, &error);
965
        if(error != NULL) {
966
                g_atomic_int_set(&initialized, 0);
967
                JANUS_LOG(LOG_ERR, "Got error %d (%s) trying to launch the SIP watchdog thread...\n", error->code, error->message ? error->message : "??");
968
                return -1;
969
        }
970
        /* Launch the thread that will handle incoming messages */
971
        handler_thread = g_thread_try_new("sip handler", janus_sip_handler, NULL, &error);
972
        if(error != NULL) {
973
                g_atomic_int_set(&initialized, 0);
974
                JANUS_LOG(LOG_ERR, "Got error %d (%s) trying to launch the SIP handler thread...\n", error->code, error->message ? error->message : "??");
975
                return -1;
976
        }
977
        JANUS_LOG(LOG_INFO, "%s initialized!\n", JANUS_SIP_NAME);
978
        return 0;
979
}
980

    
981
void janus_sip_destroy(void) {
982
        if(!g_atomic_int_get(&initialized))
983
                return;
984
        g_atomic_int_set(&stopping, 1);
985

    
986
        g_async_queue_push(messages, &exit_message);
987
        if(handler_thread != NULL) {
988
                g_thread_join(handler_thread);
989
                handler_thread = NULL;
990
        }
991
        if(watchdog != NULL) {
992
                g_thread_join(watchdog);
993
                watchdog = NULL;
994
        }
995
        /* FIXME We should destroy the sessions cleanly */
996
        janus_mutex_lock(&sessions_mutex);
997
        g_hash_table_destroy(sessions);
998
        g_hash_table_destroy(callids);
999
        g_hash_table_destroy(identities);
1000
        sessions = NULL;
1001
        callids = NULL;
1002
        identities = NULL;
1003
        janus_mutex_unlock(&sessions_mutex);
1004
        g_async_queue_unref(messages);
1005
        messages = NULL;
1006
        g_atomic_int_set(&initialized, 0);
1007
        g_atomic_int_set(&stopping, 0);
1008

    
1009
        /* Deinitialize sofia */
1010
        su_deinit();
1011

    
1012
        JANUS_LOG(LOG_INFO, "%s destroyed!\n", JANUS_SIP_NAME);
1013
}
1014

    
1015
int janus_sip_get_api_compatibility(void) {
1016
        /* Important! This is what your plugin MUST always return: don't lie here or bad things will happen */
1017
        return JANUS_PLUGIN_API_VERSION;
1018
}
1019

    
1020
int janus_sip_get_version(void) {
1021
        return JANUS_SIP_VERSION;
1022
}
1023

    
1024
const char *janus_sip_get_version_string(void) {
1025
        return JANUS_SIP_VERSION_STRING;
1026
}
1027

    
1028
const char *janus_sip_get_description(void) {
1029
        return JANUS_SIP_DESCRIPTION;
1030
}
1031

    
1032
const char *janus_sip_get_name(void) {
1033
        return JANUS_SIP_NAME;
1034
}
1035

    
1036
const char *janus_sip_get_author(void) {
1037
        return JANUS_SIP_AUTHOR;
1038
}
1039

    
1040
const char *janus_sip_get_package(void) {
1041
        return JANUS_SIP_PACKAGE;
1042
}
1043

    
1044
void janus_sip_create_session(janus_plugin_session *handle, int *error) {
1045
        if(g_atomic_int_get(&stopping) || !g_atomic_int_get(&initialized)) {
1046
                *error = -1;
1047
                return;
1048
        }
1049
        janus_sip_session *session = g_malloc0(sizeof(janus_sip_session));
1050
        session->handle = handle;
1051
        session->account.identity = NULL;
1052
        session->account.sips = TRUE;
1053
        session->account.username = NULL;
1054
        session->account.display_name = NULL;
1055
        session->account.user_agent = NULL;
1056
        session->account.authuser = NULL;
1057
        session->account.secret = NULL;
1058
        session->account.secret_type = janus_sip_secret_type_unknown;
1059
        session->account.sip_port = 0;
1060
        session->account.proxy = NULL;
1061
        session->account.registration_status = janus_sip_registration_status_unregistered;
1062
        session->status = janus_sip_call_status_idle;
1063
        session->stack = NULL;
1064
        session->transaction = NULL;
1065
        session->callee = NULL;
1066
        session->callid = NULL;
1067
        session->sdp = NULL;
1068
        session->media.remote_ip = NULL;
1069
        session->media.ready = 0;
1070
        session->media.autoack = TRUE;
1071
        session->media.require_srtp = FALSE;
1072
        session->media.has_srtp_local = FALSE;
1073
        session->media.has_srtp_remote = FALSE;
1074
        session->media.has_audio = 0;
1075
        session->media.audio_rtp_fd = -1;
1076
        session->media.audio_rtcp_fd= -1;
1077
        session->media.local_audio_rtp_port = 0;
1078
        session->media.remote_audio_rtp_port = 0;
1079
        session->media.local_audio_rtcp_port = 0;
1080
        session->media.remote_audio_rtcp_port = 0;
1081
        session->media.audio_ssrc = 0;
1082
        session->media.audio_ssrc_peer = 0;
1083
        session->media.audio_pt = -1;
1084
        session->media.audio_pt_name = NULL;
1085
        session->media.audio_srtp_suite_in = 0;
1086
        session->media.audio_srtp_suite_out = 0;
1087
        session->media.audio_send = TRUE;
1088
        session->media.has_video = 0;
1089
        session->media.video_rtp_fd = -1;
1090
        session->media.video_rtcp_fd= -1;
1091
        session->media.local_video_rtp_port = 0;
1092
        session->media.remote_video_rtp_port = 0;
1093
        session->media.local_video_rtcp_port = 0;
1094
        session->media.remote_video_rtcp_port = 0;
1095
        session->media.video_ssrc = 0;
1096
        session->media.video_ssrc_peer = 0;
1097
        session->media.video_pt = -1;
1098
        session->media.video_pt_name = NULL;
1099
        session->media.video_srtp_suite_in = 0;
1100
        session->media.video_srtp_suite_out = 0;
1101
        session->media.video_send = TRUE;
1102
        /* Initialize the RTP context */
1103
        session->media.context.a_last_ssrc = 0;
1104
        session->media.context.a_last_ssrc = 0;
1105
        session->media.context.a_last_ts = 0;
1106
        session->media.context.a_base_ts = 0;
1107
        session->media.context.a_base_ts_prev = 0;
1108
        session->media.context.v_last_ssrc = 0;
1109
        session->media.context.v_last_ts = 0;
1110
        session->media.context.v_base_ts = 0;
1111
        session->media.context.v_base_ts_prev = 0;
1112
        session->media.context.a_last_seq = 0;
1113
        session->media.context.a_base_seq = 0;
1114
        session->media.context.a_base_seq_prev = 0;
1115
        session->media.context.v_last_seq = 0;
1116
        session->media.context.v_base_seq = 0;
1117
        session->media.context.v_base_seq_prev = 0;
1118
        session->media.pipefd[0] = -1;
1119
        session->media.pipefd[1] = -1;
1120
        session->media.updated = FALSE;
1121
        janus_mutex_init(&session->rec_mutex);
1122
        session->destroyed = 0;
1123
        g_atomic_int_set(&session->hangingup, 0);
1124
        janus_mutex_init(&session->mutex);
1125
        handle->plugin_handle = session;
1126

    
1127
        janus_mutex_lock(&sessions_mutex);
1128
        g_hash_table_insert(sessions, handle, session);
1129
        janus_mutex_unlock(&sessions_mutex);
1130

    
1131
        return;
1132
}
1133

    
1134
void janus_sip_destroy_session(janus_plugin_session *handle, int *error) {
1135
        if(g_atomic_int_get(&stopping) || !g_atomic_int_get(&initialized)) {
1136
                *error = -1;
1137
                return;
1138
        }
1139
        janus_sip_session *session = (janus_sip_session *)handle->plugin_handle;
1140
        if(!session) {
1141
                JANUS_LOG(LOG_ERR, "No SIP session associated with this handle...\n");
1142
                *error = -2;
1143
                return;
1144
        }
1145
        janus_mutex_lock(&sessions_mutex);
1146
        if(!session->destroyed) {
1147
                g_hash_table_remove(sessions, handle);
1148
                janus_sip_hangup_media(handle);
1149
                session->destroyed = janus_get_monotonic_time();
1150
                JANUS_LOG(LOG_VERB, "Destroying SIP session (%s)...\n", session->account.username ? session->account.username : "unregistered user");
1151
                if(session->stack != NULL) {
1152
                        /* Shutdown the NUA: this will remove the session later on */
1153
                        nua_shutdown(session->stack->s_nua);
1154
                } else {
1155
                        /* No stack, maybe never registered: cleaning up and removing the session is done in a lazy way */
1156
                        old_sessions = g_list_append(old_sessions, session);
1157
                }
1158
        }
1159
        janus_mutex_unlock(&sessions_mutex);
1160
        return;
1161
}
1162

    
1163
json_t *janus_sip_query_session(janus_plugin_session *handle) {
1164
        if(g_atomic_int_get(&stopping) || !g_atomic_int_get(&initialized)) {
1165
                return NULL;
1166
        }
1167
        janus_sip_session *session = (janus_sip_session *)handle->plugin_handle;
1168
        if(!session) {
1169
                JANUS_LOG(LOG_ERR, "No session associated with this handle...\n");
1170
                return NULL;
1171
        }
1172
        /* Provide some generic info, e.g., if we're in a call and with whom */
1173
        json_t *info = json_object();
1174
        json_object_set_new(info, "username", session->account.username ? json_string(session->account.username) : NULL);
1175
        json_object_set_new(info, "display_name", session->account.display_name ? json_string(session->account.display_name) : NULL);
1176
        json_object_set_new(info, "user_agent", session->account.user_agent ? json_string(session->account.user_agent) : NULL);
1177
        json_object_set_new(info, "identity", session->account.identity ? json_string(session->account.identity) : NULL);
1178
        json_object_set_new(info, "registration_status", json_string(janus_sip_registration_status_string(session->account.registration_status)));
1179
        json_object_set_new(info, "call_status", json_string(janus_sip_call_status_string(session->status)));
1180
        if(session->callee) {
1181
                json_object_set_new(info, "callee", json_string(session->callee ? session->callee : "??"));
1182
                json_object_set_new(info, "auto-ack", json_string(session->media.autoack ? "yes" : "no"));
1183
                json_object_set_new(info, "srtp-required", json_string(session->media.require_srtp ? "yes" : "no"));
1184
                json_object_set_new(info, "sdes-local", json_string(session->media.has_srtp_local ? "yes" : "no"));
1185
                json_object_set_new(info, "sdes-remote", json_string(session->media.has_srtp_remote ? "yes" : "no"));
1186
        }
1187
        if(session->arc || session->vrc || session->arc_peer || session->vrc_peer) {
1188
                json_t *recording = json_object();
1189
                if(session->arc && session->arc->filename)
1190
                        json_object_set_new(recording, "audio", json_string(session->arc->filename));
1191
                if(session->vrc && session->vrc->filename)
1192
                        json_object_set_new(recording, "video", json_string(session->vrc->filename));
1193
                if(session->arc_peer && session->arc_peer->filename)
1194
                        json_object_set_new(recording, "audio-peer", json_string(session->arc_peer->filename));
1195
                if(session->vrc_peer && session->vrc_peer->filename)
1196
                        json_object_set_new(recording, "video-peer", json_string(session->vrc_peer->filename));
1197
                json_object_set_new(info, "recording", recording);
1198
        }
1199
        json_object_set_new(info, "destroyed", json_integer(session->destroyed));
1200
        return info;
1201
}
1202

    
1203
struct janus_plugin_result *janus_sip_handle_message(janus_plugin_session *handle, char *transaction, json_t *message, json_t *jsep) {
1204
        if(g_atomic_int_get(&stopping) || !g_atomic_int_get(&initialized))
1205
                return janus_plugin_result_new(JANUS_PLUGIN_ERROR, g_atomic_int_get(&stopping) ? "Shutting down" : "Plugin not initialized", NULL);
1206
        janus_sip_message *msg = g_malloc0(sizeof(janus_sip_message));
1207
        msg->handle = handle;
1208
        msg->transaction = transaction;
1209
        msg->message = message;
1210
        msg->jsep = jsep;
1211
        g_async_queue_push(messages, msg);
1212

    
1213
        /* All the requests to this plugin are handled asynchronously */
1214
        return janus_plugin_result_new(JANUS_PLUGIN_OK_WAIT, NULL, NULL);
1215
}
1216

    
1217
void janus_sip_setup_media(janus_plugin_session *handle) {
1218
        JANUS_LOG(LOG_INFO, "WebRTC media is now available\n");
1219
        if(g_atomic_int_get(&stopping) || !g_atomic_int_get(&initialized))
1220
                return;
1221
        janus_sip_session *session = (janus_sip_session *)handle->plugin_handle;
1222
        if(!session) {
1223
                JANUS_LOG(LOG_ERR, "No session associated with this handle...\n");
1224
                return;
1225
        }
1226
        if(session->destroyed)
1227
                return;
1228
        g_atomic_int_set(&session->hangingup, 0);
1229
        /* TODO Only relay RTP/RTCP when we get this event */
1230
}
1231

    
1232
void janus_sip_incoming_rtp(janus_plugin_session *handle, int video, char *buf, int len) {
1233
        if(handle == NULL || handle->stopped || g_atomic_int_get(&stopping) || !g_atomic_int_get(&initialized))
1234
                return;
1235
        if(gateway) {
1236
                /* Honour the audio/video active flags */
1237
                janus_sip_session *session = (janus_sip_session *)handle->plugin_handle;
1238
                if(!session || session->destroyed) {
1239
                        JANUS_LOG(LOG_ERR, "No session associated with this handle...\n");
1240
                        return;
1241
                }
1242
                if(session->status != janus_sip_call_status_incall)
1243
                        return;
1244
                /* Forward to our SIP peer */
1245
                if(video) {
1246
                        if(!session->media.video_send) {
1247
                                /* Dropping video packet, peer doesn't want to receive it */
1248
                                return;
1249
                        }
1250
                        if(session->media.video_ssrc == 0) {
1251
                                rtp_header *header = (rtp_header *)buf;
1252
                                session->media.video_ssrc = ntohl(header->ssrc);
1253
                                JANUS_LOG(LOG_VERB, "Got SIP video SSRC: %"SCNu32"\n", session->media.video_ssrc);
1254
                        }
1255
                        if(session->media.has_video && session->media.video_rtp_fd) {
1256
                                /* Save the frame if we're recording */
1257
                                janus_recorder_save_frame(session->vrc, buf, len);
1258
                                /* Is SRTP involved? */
1259
                                if(session->media.has_srtp_local) {
1260
                                        char sbuf[2048];
1261
                                        memcpy(&sbuf, buf, len);
1262
                                        int protected = len;
1263
                                        int res = srtp_protect(session->media.video_srtp_out, &sbuf, &protected);
1264
                                        if(res != srtp_err_status_ok) {
1265
                                                rtp_header *header = (rtp_header *)&sbuf;
1266
                                                guint32 timestamp = ntohl(header->timestamp);
1267
                                                guint16 seq = ntohs(header->seq_number);
1268
                                                JANUS_LOG(LOG_ERR, "[SIP-%s] Video SRTP protect error... %s (len=%d-->%d, ts=%"SCNu32", seq=%"SCNu16")...\n",
1269
                                                        session->account.username, janus_sip_get_srtp_error(res), len, protected, timestamp, seq);
1270
                                        } else {
1271
                                                /* Forward the frame to the peer */
1272
                                                send(session->media.video_rtp_fd, sbuf, protected, 0);
1273
                                        }
1274
                                } else {
1275
                                        /* Forward the frame to the peer */
1276
                                        send(session->media.video_rtp_fd, buf, len, 0);
1277
                                }
1278
                        }
1279
                } else {
1280
                        if(!session->media.audio_send) {
1281
                                /* Dropping audio packet, peer doesn't want to receive it */
1282
                                return;
1283
                        }
1284
                        if(session->media.audio_ssrc == 0) {
1285
                                rtp_header *header = (rtp_header *)buf;
1286
                                session->media.audio_ssrc = ntohl(header->ssrc);
1287
                                JANUS_LOG(LOG_VERB, "Got SIP audio SSRC: %"SCNu32"\n", session->media.audio_ssrc);
1288
                        }
1289
                        if(session->media.has_audio && session->media.audio_rtp_fd) {
1290
                                /* Save the frame if we're recording */
1291
                                janus_recorder_save_frame(session->arc, buf, len);
1292
                                /* Is SRTP involved? */
1293
                                if(session->media.has_srtp_local) {
1294
                                        char sbuf[2048];
1295
                                        memcpy(&sbuf, buf, len);
1296
                                        int protected = len;
1297
                                        int res = srtp_protect(session->media.audio_srtp_out, &sbuf, &protected);
1298
                                        if(res != srtp_err_status_ok) {
1299
                                                rtp_header *header = (rtp_header *)&sbuf;
1300
                                                guint32 timestamp = ntohl(header->timestamp);
1301
                                                guint16 seq = ntohs(header->seq_number);
1302
                                                JANUS_LOG(LOG_ERR, "[SIP-%s] Audio SRTP protect error... %s (len=%d-->%d, ts=%"SCNu32", seq=%"SCNu16")...\n",
1303
                                                        session->account.username, janus_sip_get_srtp_error(res), len, protected, timestamp, seq);
1304
                                        } else {
1305
                                                /* Forward the frame to the peer */
1306
                                                send(session->media.audio_rtp_fd, sbuf, protected, 0);
1307
                                        }
1308
                                } else {
1309
                                        /* Forward the frame to the peer */
1310
                                        send(session->media.audio_rtp_fd, buf, len, 0);
1311
                                }
1312
                        }
1313
                }
1314
        }
1315
}
1316

    
1317
void janus_sip_incoming_rtcp(janus_plugin_session *handle, int video, char *buf, int len) {
1318
        if(handle == NULL || handle->stopped || g_atomic_int_get(&stopping) || !g_atomic_int_get(&initialized))
1319
                return;
1320
        if(gateway) {
1321
                janus_sip_session *session = (janus_sip_session *)handle->plugin_handle;
1322
                if(!session || session->destroyed) {
1323
                        JANUS_LOG(LOG_ERR, "No session associated with this handle...\n");
1324
                        return;
1325
                }
1326
                if(session->status != janus_sip_call_status_incall)
1327
                        return;
1328
                /* Forward to our SIP peer */
1329
                if(video) {
1330
                        if(session->media.has_video && session->media.video_rtcp_fd) {
1331
                                /* Fix SSRCs as the gateway does */
1332
                                JANUS_LOG(LOG_HUGE, "[SIP] Fixing SSRCs (local %u, peer %u)\n",
1333
                                        session->media.video_ssrc, session->media.video_ssrc_peer);
1334
                                janus_rtcp_fix_ssrc(NULL, (char *)buf, len, 1, session->media.video_ssrc, session->media.video_ssrc_peer);
1335
                                /* Is SRTP involved? */
1336
                                if(session->media.has_srtp_local) {
1337
                                        char sbuf[2048];
1338
                                        memcpy(&sbuf, buf, len);
1339
                                        int protected = len;
1340
                                        int res = srtp_protect_rtcp(session->media.video_srtp_out, &sbuf, &protected);
1341
                                        if(res != srtp_err_status_ok) {
1342
                                                JANUS_LOG(LOG_ERR, "[SIP-%s] Video SRTCP protect error... %s (len=%d-->%d)...\n",
1343
                                                        session->account.username, janus_sip_get_srtp_error(res), len, protected);
1344
                                        } else {
1345
                                                /* Forward the message to the peer */
1346
                                                send(session->media.video_rtcp_fd, sbuf, protected, 0);
1347
                                        }
1348
                                } else {
1349
                                        /* Forward the message to the peer */
1350
                                        send(session->media.video_rtcp_fd, buf, len, 0);
1351
                                }
1352
                        }
1353
                } else {
1354
                        if(session->media.has_audio && session->media.audio_rtcp_fd) {
1355
                                /* Fix SSRCs as the gateway does */
1356
                                JANUS_LOG(LOG_HUGE, "[SIP] Fixing SSRCs (local %u, peer %u)\n",
1357
                                        session->media.audio_ssrc, session->media.audio_ssrc_peer);
1358
                                janus_rtcp_fix_ssrc(NULL, (char *)buf, len, 1, session->media.audio_ssrc, session->media.audio_ssrc_peer);
1359
                                /* Is SRTP involved? */
1360
                                if(session->media.has_srtp_local) {
1361
                                        char sbuf[2048];
1362
                                        memcpy(&sbuf, buf, len);
1363
                                        int protected = len;
1364
                                        int res = srtp_protect_rtcp(session->media.audio_srtp_out, &sbuf, &protected);
1365
                                        if(res != srtp_err_status_ok) {
1366
                                                JANUS_LOG(LOG_ERR, "[SIP-%s] Audio SRTCP protect error... %s (len=%d-->%d)...\n",
1367
                                                        session->account.username, janus_sip_get_srtp_error(res), len, protected);
1368
                                        } else {
1369
                                                /* Forward the message to the peer */
1370
                                                send(session->media.audio_rtcp_fd, sbuf, protected, 0);
1371
                                        }
1372
                                } else {
1373
                                        /* Forward the message to the peer */
1374
                                        send(session->media.audio_rtcp_fd, buf, len, 0);
1375
                                }
1376
                        }
1377
                }
1378
        }
1379
}
1380

    
1381
void janus_sip_hangup_media(janus_plugin_session *handle) {
1382
        JANUS_LOG(LOG_INFO, "No WebRTC media anymore\n");
1383
        if(g_atomic_int_get(&stopping) || !g_atomic_int_get(&initialized))
1384
                return;
1385
        janus_sip_session *session = (janus_sip_session *)handle->plugin_handle;
1386
        if(!session) {
1387
                JANUS_LOG(LOG_ERR, "No session associated with this handle...\n");
1388
                return;
1389
        }
1390
        if(session->destroyed)
1391
                return;
1392
        if(g_atomic_int_add(&session->hangingup, 1))
1393
                return;
1394
        if(!(session->status == janus_sip_call_status_inviting ||
1395
                 session->status == janus_sip_call_status_invited ||
1396
                 session->status == janus_sip_call_status_incall))
1397
                return;
1398
        /* Get rid of the recorders, if available */
1399
        janus_mutex_lock(&session->rec_mutex);
1400
        if(session->arc) {
1401
                janus_recorder_close(session->arc);
1402
                JANUS_LOG(LOG_INFO, "Closed user's audio recording %s\n", session->arc->filename ? session->arc->filename : "??");
1403
                janus_recorder_free(session->arc);
1404
        }
1405
        session->arc = NULL;
1406
        if(session->arc_peer) {
1407
                janus_recorder_close(session->arc_peer);
1408
                JANUS_LOG(LOG_INFO, "Closed peer's audio recording %s\n", session->arc_peer->filename ? session->arc_peer->filename : "??");
1409
                janus_recorder_free(session->arc_peer);
1410
        }
1411
        session->arc_peer = NULL;
1412
        if(session->vrc) {
1413
                janus_recorder_close(session->vrc);
1414
                JANUS_LOG(LOG_INFO, "Closed user's video recording %s\n", session->vrc->filename ? session->vrc->filename : "??");
1415
                janus_recorder_free(session->vrc);
1416
        }
1417
        session->vrc = NULL;
1418
        if(session->vrc_peer) {
1419
                janus_recorder_close(session->vrc_peer);
1420
                JANUS_LOG(LOG_INFO, "Closed peer's video recording %s\n", session->vrc_peer->filename ? session->vrc_peer->filename : "??");
1421
                janus_recorder_free(session->vrc_peer);
1422
        }
1423
        session->vrc_peer = NULL;
1424
        janus_mutex_unlock(&session->rec_mutex);
1425
        /* FIXME Simulate a "hangup" coming from the browser */
1426
        janus_sip_message *msg = g_malloc0(sizeof(janus_sip_message));
1427
        msg->handle = handle;
1428
        msg->message = json_pack("{ss}", "request", "hangup");
1429
        msg->transaction = NULL;
1430
        msg->jsep = NULL;
1431
        g_async_queue_push(messages, msg);
1432
}
1433

    
1434
/* Thread to handle incoming messages */
1435
static void *janus_sip_handler(void *data) {
1436
        JANUS_LOG(LOG_VERB, "Joining SIP handler thread\n");
1437
        janus_sip_message *msg = NULL;
1438
        int error_code = 0;
1439
        char error_cause[512];
1440
        json_t *root = NULL;
1441
        while(g_atomic_int_get(&initialized) && !g_atomic_int_get(&stopping)) {
1442
                msg = g_async_queue_pop(messages);
1443
                if(msg == NULL)
1444
                        continue;
1445
                if(msg == &exit_message)
1446
                        break;
1447
                if(msg->handle == NULL) {
1448
                        janus_sip_message_free(msg);
1449
                        continue;
1450
                }
1451
                janus_sip_session *session = NULL;
1452
                janus_mutex_lock(&sessions_mutex);
1453
                if(g_hash_table_lookup(sessions, msg->handle) != NULL ) {
1454
                        session = (janus_sip_session *)msg->handle->plugin_handle;
1455
                }
1456
                janus_mutex_unlock(&sessions_mutex);
1457
                if(!session) {
1458
                        JANUS_LOG(LOG_ERR, "No session associated with this handle...\n");
1459
                        janus_sip_message_free(msg);
1460
                        continue;
1461
                }
1462
                if(session->destroyed) {
1463
                        janus_sip_message_free(msg);
1464
                        continue;
1465
                }
1466
                /* Handle request */
1467
                error_code = 0;
1468
                root = msg->message;
1469
                if(msg->message == NULL) {
1470
                        JANUS_LOG(LOG_ERR, "No message??\n");
1471
                        error_code = JANUS_SIP_ERROR_NO_MESSAGE;
1472
                        g_snprintf(error_cause, 512, "%s", "No message??");
1473
                        goto error;
1474
                }
1475
                if(!json_is_object(root)) {
1476
                        JANUS_LOG(LOG_ERR, "JSON error: not an object\n");
1477
                        error_code = JANUS_SIP_ERROR_INVALID_JSON;
1478
                        g_snprintf(error_cause, 512, "JSON error: not an object");
1479
                        goto error;
1480
                }
1481
                JANUS_VALIDATE_JSON_OBJECT(root, request_parameters,
1482
                        error_code, error_cause, TRUE,
1483
                        JANUS_SIP_ERROR_MISSING_ELEMENT, JANUS_SIP_ERROR_INVALID_ELEMENT);
1484
                if(error_code != 0)
1485
                        goto error;
1486
                json_t *request = json_object_get(root, "request");
1487
                const char *request_text = json_string_value(request);
1488
                json_t *result = NULL;
1489

    
1490
                if(!strcasecmp(request_text, "register")) {
1491
                        /* Send a REGISTER */
1492
                        if(session->account.registration_status > janus_sip_registration_status_unregistered) {
1493
                                JANUS_LOG(LOG_ERR, "Already registered (%s)\n", session->account.username);
1494
                                error_code = JANUS_SIP_ERROR_ALREADY_REGISTERED;
1495
                                g_snprintf(error_cause, 512, "Already registered (%s)", session->account.username);
1496
                                goto error;
1497
                        }
1498

    
1499
                        /* Cleanup old values */
1500
                        if(session->account.identity != NULL) {
1501
                                g_hash_table_remove(identities, session->account.identity);
1502
                                g_free(session->account.identity);
1503
                        }
1504
                        session->account.identity = NULL;
1505
                        session->account.sips = TRUE;
1506
                        if(session->account.username != NULL)
1507
                                g_free(session->account.username);
1508
                        session->account.username = NULL;
1509
                        if(session->account.display_name != NULL)
1510
                                g_free(session->account.display_name);
1511
                        session->account.display_name = NULL;
1512
                        if(session->account.authuser != NULL)
1513
                                g_free(session->account.authuser);
1514
                        session->account.authuser = NULL;
1515
                        if(session->account.secret != NULL)
1516
                                g_free(session->account.secret);
1517
                        session->account.secret = NULL;
1518
                        session->account.secret_type = janus_sip_secret_type_unknown;
1519
                        if(session->account.proxy != NULL)
1520
                                g_free(session->account.proxy);
1521
                        session->account.proxy = NULL;
1522
                        if(session->account.user_agent != NULL)
1523
                                g_free(session->account.user_agent);
1524
                        session->account.user_agent = NULL;
1525
                        session->account.registration_status = janus_sip_registration_status_unregistered;
1526

    
1527
                        gboolean guest = FALSE;
1528
                        JANUS_VALIDATE_JSON_OBJECT(root, register_parameters,
1529
                                error_code, error_cause, TRUE,
1530
                                JANUS_SIP_ERROR_MISSING_ELEMENT, JANUS_SIP_ERROR_INVALID_ELEMENT);
1531
                        if(error_code != 0)
1532
                                goto error;
1533
                        json_t *type = json_object_get(root, "type");
1534
                        if(type != NULL) {
1535
                                const char *type_text = json_string_value(type);
1536
                                if(!strcmp(type_text, "guest")) {
1537
                                        JANUS_LOG(LOG_INFO, "Registering as a guest\n");
1538
                                        guest = TRUE;
1539
                                } else {
1540
                                        JANUS_LOG(LOG_WARN, "Unknown type '%s', ignoring...\n", type_text);
1541
                                }
1542
                        }
1543

    
1544
                        gboolean send_register = TRUE;
1545
                        json_t *do_register = json_object_get(root, "send_register");
1546
                        if(do_register != NULL) {
1547
                                if(guest) {
1548
                                        JANUS_LOG(LOG_ERR, "Conflicting elements: send_register cannot be true if guest is true\n");
1549
                                        error_code = JANUS_SIP_ERROR_INVALID_ELEMENT;
1550
                                        g_snprintf(error_cause, 512, "Conflicting elements: send_register cannot be true if guest is true");
1551
                                        goto error;
1552
                                }
1553
                                send_register = json_is_true(do_register);
1554
                        }
1555

    
1556
                        gboolean sips = TRUE;
1557
                        json_t *do_sips = json_object_get(root, "sips");
1558
                        if(do_sips != NULL) {
1559
                                sips = json_is_true(do_sips);
1560
                        }
1561

    
1562
                        /* Parse address */
1563
                        json_t *proxy = json_object_get(root, "proxy");
1564
                        const char *proxy_text = NULL;
1565

    
1566
                        if (proxy && !json_is_null(proxy)) {
1567
                                /* Has to be validated separately because it could be null */
1568
                                JANUS_VALIDATE_JSON_OBJECT(root, proxy_parameters,
1569
                                        error_code, error_cause, TRUE,
1570
                                        JANUS_SIP_ERROR_MISSING_ELEMENT, JANUS_SIP_ERROR_INVALID_ELEMENT);
1571
                                if(error_code != 0)
1572
                                        goto error;
1573
                                proxy_text = json_string_value(proxy);
1574
                                janus_sip_uri_t proxy_uri;
1575
                                if (janus_sip_parse_proxy_uri(&proxy_uri, proxy_text) < 0) {
1576
                                        JANUS_LOG(LOG_ERR, "Invalid proxy address %s\n", proxy_text);
1577
                                        error_code = JANUS_SIP_ERROR_INVALID_ADDRESS;
1578
                                        g_snprintf(error_cause, 512, "Invalid proxy address %s\n", proxy_text);
1579
                                        goto error;
1580
                                }
1581
                        }
1582

    
1583
                        /* Parse register TTL */
1584
                        int ttl = register_ttl;
1585
                        json_t *reg_ttl = json_object_get(root, "register_ttl");
1586
                        if (reg_ttl && json_is_integer(reg_ttl))
1587
                                ttl = json_integer_value(reg_ttl);
1588
                        if (ttl <= 0)
1589
                                ttl = JANUS_DEFAULT_REGISTER_TTL;
1590

    
1591
                        /* Parse display name */
1592
                        const char* display_name_text = NULL;
1593
                        json_t *display_name = json_object_get(root, "display_name");
1594
                        if (display_name && json_is_string(display_name))
1595
                                display_name_text = json_string_value(display_name);
1596

    
1597
                        /* Parse user agent */
1598
                        const char* user_agent_text = NULL;
1599
                        json_t *user_agent = json_object_get(root, "user_agent");
1600
                        if (user_agent && json_is_string(user_agent))
1601
                                user_agent_text = json_string_value(user_agent);
1602

    
1603
                        /* Now the user part, if needed */
1604
                        json_t *username = json_object_get(root, "username");
1605
                        if(!guest && !username) {
1606
                                /* The username is mandatory if we're not registering as guests */
1607
                                JANUS_LOG(LOG_ERR, "Missing element (username)\n");
1608
                                error_code = JANUS_SIP_ERROR_MISSING_ELEMENT;
1609
                                g_snprintf(error_cause, 512, "Missing element (username)");
1610
                                goto error;
1611
                        }
1612
                        const char *username_text = NULL;
1613
                        janus_sip_uri_t username_uri;
1614
                        char user_id[256];
1615
                        if(username) {
1616
                                /* Parse address */
1617
                                username_text = json_string_value(username);
1618
                                if (janus_sip_parse_uri(&username_uri, username_text) < 0) {
1619
                                        JANUS_LOG(LOG_ERR, "Invalid user address %s\n", username_text);
1620
                                        error_code = JANUS_SIP_ERROR_INVALID_ADDRESS;
1621
                                        g_snprintf(error_cause, 512, "Invalid user address %s\n", username_text);
1622
                                        goto error;
1623
                                }
1624
                                g_strlcpy(user_id, username_uri.url->url_user, sizeof(user_id));
1625
                        }
1626
                        if(guest) {
1627
                                /* Not needed, we can stop here: just pick a random username if it wasn't provided and say we're registered */
1628
                                if(!username)
1629
                                        g_snprintf(user_id, 255, "janus-sip-%"SCNu32"", janus_random_uint32());
1630
                                JANUS_LOG(LOG_INFO, "Guest will have username %s\n", user_id);
1631
                                send_register = FALSE;
1632
                        } else {
1633
                                json_t *secret = json_object_get(root, "secret");
1634
                                json_t *ha1_secret = json_object_get(root, "ha1_secret");
1635
                                json_t *authuser = json_object_get(root, "authuser");
1636
                                if(!secret && !ha1_secret) {
1637
                                        JANUS_LOG(LOG_ERR, "Missing element (secret or ha1_secret)\n");
1638
                                        error_code = JANUS_SIP_ERROR_MISSING_ELEMENT;
1639
                                        g_snprintf(error_cause, 512, "Missing element (secret or ha1_secret)");
1640
                                        goto error;
1641
                                }
1642
                                if(secret && ha1_secret) {
1643
                                        JANUS_LOG(LOG_ERR, "Conflicting elements specified (secret and ha1_secret)\n");
1644
                                        error_code = JANUS_SIP_ERROR_INVALID_ELEMENT;
1645
                                        g_snprintf(error_cause, 512, "Conflicting elements specified (secret and ha1_secret)");
1646
                                        goto error;
1647
                                }
1648
                                const char *secret_text;
1649
                                if(secret) {
1650
                                        secret_text = json_string_value(secret);
1651
                                        session->account.secret = g_strdup(secret_text);
1652
                                        session->account.secret_type = janus_sip_secret_type_plaintext;
1653
                                } else {
1654
                                        secret_text = json_string_value(ha1_secret);
1655
                                        session->account.secret = g_strdup(secret_text);
1656
                                        session->account.secret_type = janus_sip_secret_type_hashed;
1657
                                }
1658
                                if (authuser) {
1659
                                        const char *authuser_text;
1660
                                        authuser_text = json_string_value(authuser);
1661
                                        session->account.authuser = g_strdup(authuser_text);
1662
                                } else {
1663
                                        session->account.authuser = g_strdup(user_id);
1664
                                }
1665
                                /* Got the values, try registering now */
1666
                                JANUS_LOG(LOG_VERB, "Registering user %s (secret %s) @ %s through %s\n",
1667
                                        username_text, secret_text, username_uri.url->url_host, proxy_text != NULL ? proxy_text : "(null)");
1668
                        }
1669

    
1670
                        session->account.identity = g_strdup(username_text);
1671
                        g_hash_table_insert(identities, session->account.identity, session);
1672
                        session->account.sips = sips;
1673
                        session->account.username = g_strdup(user_id);
1674
                        if (display_name_text) {
1675
                                session->account.display_name = g_strdup(display_name_text);
1676
                        }
1677
                        if (user_agent_text) {
1678
                                session->account.user_agent = g_strdup(user_agent_text);
1679
                        }
1680
                        if (proxy_text) {
1681
                                session->account.proxy = g_strdup(proxy_text);
1682
                        }
1683

    
1684
                        session->account.registration_status = janus_sip_registration_status_registering;
1685
                        if(session->stack == NULL) {
1686
                                /* Start the thread first */
1687
                                GError *error = NULL;
1688
                                char tname[16];
1689
                                g_snprintf(tname, sizeof(tname), "sip %s", session->account.username);
1690
                                g_thread_try_new(tname, janus_sip_sofia_thread, session, &error);
1691
                                if(error != NULL) {
1692
                                        JANUS_LOG(LOG_ERR, "Got error %d (%s) trying to launch the SIP Sofia thread...\n", error->code, error->message ? error->message : "??");
1693
                                        error_code = JANUS_SIP_ERROR_UNKNOWN_ERROR;
1694
                                        g_snprintf(error_cause, 512, "Got error %d (%s) trying to launch the SIP Sofia thread", error->code, error->message ? error->message : "??");
1695
                                        goto error;
1696
                                }
1697
                                long int timeout = 0;
1698
                                while(session->stack == NULL || session->stack->s_nua == NULL) {
1699
                                        g_usleep(100000);
1700
                                        timeout += 100000;
1701
                                        if(timeout >= 2000000) {
1702
                                                break;
1703
                                        }
1704
                                }
1705
                                if(timeout >= 2000000) {
1706
                                        JANUS_LOG(LOG_ERR, "Two seconds passed and still no NUA, problems with the thread?\n");
1707
                                        error_code = JANUS_SIP_ERROR_UNKNOWN_ERROR;
1708
                                        g_snprintf(error_cause, 512, "Two seconds passed and still no NUA, problems with the thread?");
1709
                                        goto error;
1710
                                }
1711
                        }
1712
                        if(session->stack->s_nh_r != NULL) {
1713
                                nua_handle_destroy(session->stack->s_nh_r);
1714
                                session->stack->s_nh_r = NULL;
1715
                        }
1716

    
1717
                        if (send_register) {
1718
                                session->stack->s_nh_r = nua_handle(session->stack->s_nua, session, TAG_END());
1719
                                if(session->stack->s_nh_r == NULL) {
1720
                                        JANUS_LOG(LOG_ERR, "NUA Handle for REGISTER still null??\n");
1721
                                        error_code = JANUS_SIP_ERROR_LIBSOFIA_ERROR;
1722
                                        g_snprintf(error_cause, 512, "Invalid NUA Handle");
1723
                                        goto error;
1724
                                }
1725
                                char ttl_text[20];
1726
                                g_snprintf(ttl_text, sizeof(ttl_text), "%d", ttl);
1727
                                nua_register(session->stack->s_nh_r,
1728
                                        NUTAG_M_USERNAME(session->account.username),
1729
                                        SIPTAG_FROM_STR(username_text),
1730
                                        SIPTAG_TO_STR(username_text),
1731
                                        SIPTAG_EXPIRES_STR(ttl_text),
1732
                                        NUTAG_PROXY(proxy_text),
1733
                                        TAG_END());
1734
                                result = json_object();
1735
                                json_object_set_new(result, "event", json_string("registering"));
1736
                        } else {
1737
                                JANUS_LOG(LOG_VERB, "Not sending a SIP REGISTER: either send_register was set to false or guest mode was enabled\n");
1738
                                session->account.registration_status = janus_sip_registration_status_disabled;
1739
                                result = json_object();
1740
                                json_object_set_new(result, "event", json_string("registered"));
1741
                                json_object_set_new(result, "username", json_string(session->account.username));
1742
                                json_object_set_new(result, "register_sent", json_false());
1743
                                /* Also notify event handlers */
1744
                                if(notify_events && gateway->events_is_enabled()) {
1745
                                        json_t *info = json_object();
1746
                                        json_object_set_new(info, "event", json_string("registered"));
1747
                                        json_object_set_new(info, "identity", json_string(session->account.identity));
1748
                                        json_object_set_new(info, "type", json_string("guest"));
1749
                                        gateway->notify_event(&janus_sip_plugin, session->handle, info);
1750
                                }
1751
                        }
1752
                } else if(!strcasecmp(request_text, "call")) {
1753
                        /* Call another peer */
1754
                        if(session->stack == NULL) {
1755
                                JANUS_LOG(LOG_ERR, "Wrong state (register first)\n");
1756
                                error_code = JANUS_SIP_ERROR_WRONG_STATE;
1757
                                g_snprintf(error_cause, 512, "Wrong state (register first)");
1758
                                goto error;
1759
                        }
1760
                        if(session->status >= janus_sip_call_status_inviting) {
1761
                                JANUS_LOG(LOG_ERR, "Wrong state (already in a call? status=%s)\n", janus_sip_call_status_string(session->status));
1762
                                error_code = JANUS_SIP_ERROR_WRONG_STATE;
1763
                                g_snprintf(error_cause, 512, "Wrong state (already in a call? status=%s)", janus_sip_call_status_string(session->status));
1764
                                goto error;
1765
                        }
1766
                        JANUS_VALIDATE_JSON_OBJECT(root, call_parameters,
1767
                                error_code, error_cause, TRUE,
1768
                                JANUS_SIP_ERROR_MISSING_ELEMENT, JANUS_SIP_ERROR_INVALID_ELEMENT);
1769
                        if(error_code != 0)
1770
                                goto error;
1771
                        json_t *uri = json_object_get(root, "uri");
1772
                        /* Check if we need to ACK manually (e.g., for the Record-Route hack) */
1773
                        json_t *autoack = json_object_get(root, "autoack");
1774
                        gboolean do_autoack = autoack ? json_is_true(autoack) : TRUE;
1775
                        /* Check if the INVITE needs to be enriched with custom headers */
1776
                        char custom_headers[2048];
1777
                        custom_headers[0] = '\0';
1778
                        json_t *headers = json_object_get(root, "headers");
1779
                        if(headers) {
1780
                                if(json_object_size(headers) > 0) {
1781
                                        /* Parse custom headers */
1782
                                        const char *key = NULL;
1783
                                        json_t *value = NULL;
1784
                                        void *iter = json_object_iter(headers);
1785
                                        while(iter != NULL) {
1786
                                                key = json_object_iter_key(iter);
1787
                                                value = json_object_get(headers, key);
1788
                                                if(value == NULL || !json_is_string(value)) {
1789
                                                        JANUS_LOG(LOG_WARN, "Skipping header '%s': value is not a string\n", key);
1790
                                                        iter = json_object_iter_next(headers, iter);
1791
                                                        continue;
1792
                                                }
1793
                                                char h[255];
1794
                                                g_snprintf(h, 255, "%s: %s\r\n", key, json_string_value(value));
1795
                                                JANUS_LOG(LOG_VERB, "Adding custom header, %s", h);
1796
                                                g_strlcat(custom_headers, h, 2048);
1797
                                                iter = json_object_iter_next(headers, iter);
1798
                                        }
1799
                                }
1800
                        }
1801
                        /* SDES-SRTP is disabled by default, let's see if we need to enable it */
1802
                        gboolean offer_srtp = FALSE, require_srtp = FALSE;
1803
                        json_t *srtp = json_object_get(root, "srtp");
1804
                        if(srtp) {
1805
                                const char *srtp_text = json_string_value(srtp);
1806
                                if(!strcasecmp(srtp_text, "sdes_optional")) {
1807
                                        /* Negotiate SDES, but make it optional */
1808
                                        offer_srtp = TRUE;
1809
                                } else if(!strcasecmp(srtp_text, "sdes_mandatory")) {
1810
                                        /* Negotiate SDES, and require it */
1811
                                        offer_srtp = TRUE;
1812
                                        require_srtp = TRUE;
1813
                                } else {
1814
                                        JANUS_LOG(LOG_ERR, "Invalid element (srtp can only be sdes_optional or sdes_mandatory)\n");
1815
                                        error_code = JANUS_SIP_ERROR_INVALID_ELEMENT;
1816
                                        g_snprintf(error_cause, 512, "Invalid element (srtp can only be sdes_optional or sdes_mandatory)");
1817
                                        goto error;
1818
                                }
1819
                        }
1820
                        /* Parse address */
1821
                        const char *uri_text = json_string_value(uri);
1822
                        janus_sip_uri_t target_uri;
1823
                        if (janus_sip_parse_uri(&target_uri, uri_text) < 0) {
1824
                                JANUS_LOG(LOG_ERR, "Invalid user address %s\n", uri_text);
1825
                                error_code = JANUS_SIP_ERROR_INVALID_ADDRESS;
1826
                                g_snprintf(error_cause, 512, "Invalid user address %s\n", uri_text);
1827
                                goto error;
1828
                        }
1829
                        /* Any SDP to handle? if not, something's wrong */
1830
                        const char *msg_sdp_type = json_string_value(json_object_get(msg->jsep, "type"));
1831
                        const char *msg_sdp = json_string_value(json_object_get(msg->jsep, "sdp"));
1832
                        if(!msg_sdp) {
1833
                                JANUS_LOG(LOG_ERR, "Missing SDP\n");
1834
                                error_code = JANUS_SIP_ERROR_MISSING_SDP;
1835
                                g_snprintf(error_cause, 512, "Missing SDP");
1836
                                goto error;
1837
                        }
1838
                        if(strstr(msg_sdp, "m=application")) {
1839
                                JANUS_LOG(LOG_ERR, "The SIP plugin does not support DataChannels\n");
1840
                                error_code = JANUS_SIP_ERROR_MISSING_SDP;
1841
                                g_snprintf(error_cause, 512, "The SIP plugin does not support DataChannels");
1842
                                goto error;
1843
                        }
1844
                        JANUS_LOG(LOG_VERB, "%s is calling %s\n", session->account.username, uri_text);
1845
                        JANUS_LOG(LOG_VERB, "This is involving a negotiation (%s) as well:\n%s\n", msg_sdp_type, msg_sdp);
1846
                        /* Clean up SRTP stuff from before first, in case it's still needed */
1847
                        janus_sip_srtp_cleanup(session);
1848
                        session->media.require_srtp = require_srtp;
1849
                        session->media.has_srtp_local = offer_srtp;
1850
                        if(offer_srtp) {
1851
                                JANUS_LOG(LOG_VERB, "Going to negotiate SDES-SRTP (%s)...\n", require_srtp ? "mandatory" : "optional");
1852
                        }
1853
                        /* Parse the SDP we got, manipulate some things, and generate a new one */
1854
                        char sdperror[100];
1855
                        janus_sdp *parsed_sdp = janus_sdp_parse(msg_sdp, sdperror, sizeof(sdperror));
1856
                        if(!parsed_sdp) {
1857
                                JANUS_LOG(LOG_ERR, "Error parsing SDP: %s\n", sdperror);
1858
                                error_code = JANUS_SIP_ERROR_MISSING_SDP;
1859
                                g_snprintf(error_cause, 512, "Error parsing SDP: %s", sdperror);
1860
                                goto error;
1861
                        }
1862
                        /* Allocate RTP ports and merge them with the anonymized SDP */
1863
                        if(strstr(msg_sdp, "m=audio") && !strstr(msg_sdp, "m=audio 0")) {
1864
                                JANUS_LOG(LOG_VERB, "Going to negotiate audio...\n");
1865
                                session->media.has_audio = 1;        /* FIXME Maybe we need a better way to signal this */
1866
                        }
1867
                        if(strstr(msg_sdp, "m=video") && !strstr(msg_sdp, "m=video 0")) {
1868
                                JANUS_LOG(LOG_VERB, "Going to negotiate video...\n");
1869
                                session->media.has_video = 1;        /* FIXME Maybe we need a better way to signal this */
1870
                        }
1871
                        if(janus_sip_allocate_local_ports(session) < 0) {
1872
                                JANUS_LOG(LOG_ERR, "Could not allocate RTP/RTCP ports\n");
1873
                                janus_sdp_free(parsed_sdp);
1874
                                error_code = JANUS_SIP_ERROR_IO_ERROR;
1875
                                g_snprintf(error_cause, 512, "Could not allocate RTP/RTCP ports");
1876
                                goto error;
1877
                        }
1878
                        char *sdp = janus_sip_sdp_manipulate(session, parsed_sdp, FALSE);
1879
                        if(sdp == NULL) {
1880
                                JANUS_LOG(LOG_ERR, "Could not allocate RTP/RTCP ports\n");
1881
                                janus_sdp_free(parsed_sdp);
1882
                                error_code = JANUS_SIP_ERROR_IO_ERROR;
1883
                                g_snprintf(error_cause, 512, "Could not allocate RTP/RTCP ports");
1884
                                goto error;
1885
                        }
1886
                        /* Take note of the SDP (may be useful for UPDATEs or re-INVITEs) */
1887
                        janus_sdp_free(session->sdp);
1888
                        session->sdp = parsed_sdp;
1889
                        JANUS_LOG(LOG_VERB, "Prepared SDP for INVITE:\n%s", sdp);
1890
                        /* Prepare the From header */
1891
                        char from_hdr[1024];
1892
                        if (session->account.display_name) {
1893
                                g_snprintf(from_hdr, sizeof(from_hdr), "\"%s\" <%s>", session->account.display_name, session->account.identity);
1894
                        } else {
1895
                                g_snprintf(from_hdr, sizeof(from_hdr), "%s", session->account.identity);
1896
                        }
1897
                        /* Prepare the stack */
1898
                        if(session->stack->s_nh_i != NULL)
1899
                                nua_handle_destroy(session->stack->s_nh_i);
1900
                        session->stack->s_nh_i = nua_handle(session->stack->s_nua, session, TAG_END());
1901
                        if(session->stack->s_nh_i == NULL) {
1902
                                JANUS_LOG(LOG_WARN, "NUA Handle for INVITE still null??\n");
1903
                                g_free(sdp);
1904
                                session->sdp = NULL;
1905
                                janus_sdp_free(parsed_sdp);
1906
                                error_code = JANUS_SIP_ERROR_LIBSOFIA_ERROR;
1907
                                g_snprintf(error_cause, 512, "Invalid NUA Handle");
1908
                                goto error;
1909
                        }
1910
                        g_atomic_int_set(&session->hangingup, 0);
1911
                        session->status = janus_sip_call_status_inviting;
1912
                        /* Create a random call-id */
1913
                        char callid[24];
1914
                        janus_sip_random_string(24, (char *)&callid);
1915
                        /* Also notify event handlers */
1916
                        if(notify_events && gateway->events_is_enabled()) {
1917
                                json_t *info = json_object();
1918
                                json_object_set_new(info, "event", json_string("calling"));
1919
                                json_object_set_new(info, "callee", json_string(uri_text));
1920
                                json_object_set_new(info, "call-id", json_string(callid));
1921
                                json_object_set_new(info, "sdp", json_string(sdp));
1922
                                gateway->notify_event(&janus_sip_plugin, session->handle, info);
1923
                        }
1924
                        /* Send INVITE */
1925
                        session->callee = g_strdup(uri_text);
1926
                        session->callid = g_strdup(callid);
1927
                        g_hash_table_insert(callids, session->callid, session);
1928
                        session->media.autoack = do_autoack;
1929
                        nua_invite(session->stack->s_nh_i,
1930
                                SIPTAG_FROM_STR(from_hdr),
1931
                                SIPTAG_TO_STR(uri_text),
1932
                                SIPTAG_CALL_ID_STR(callid),
1933
                                SOATAG_USER_SDP_STR(sdp),
1934
                                NUTAG_PROXY(session->account.proxy),
1935
                                TAG_IF(strlen(custom_headers) > 0, SIPTAG_HEADER_STR(custom_headers)),
1936
                                NUTAG_AUTOANSWER(0),
1937
                                NUTAG_AUTOACK(do_autoack),
1938
                                TAG_END());
1939
                        g_free(sdp);
1940
                        if(session->transaction)
1941
                                g_free(session->transaction);
1942
                        session->transaction = msg->transaction ? g_strdup(msg->transaction) : NULL;
1943
                        /* Send an ack back */
1944
                        result = json_object();
1945
                        json_object_set_new(result, "event", json_string("calling"));
1946
                } else if(!strcasecmp(request_text, "accept")) {
1947
                        if(session->status != janus_sip_call_status_invited) {
1948
                                JANUS_LOG(LOG_ERR, "Wrong state (not invited? status=%s)\n", janus_sip_call_status_string(session->status));
1949
                                error_code = JANUS_SIP_ERROR_WRONG_STATE;
1950
                                g_snprintf(error_cause, 512, "Wrong state (not invited? status=%s)", janus_sip_call_status_string(session->status));
1951
                                goto error;
1952
                        }
1953
                        if(session->callee == NULL) {
1954
                                JANUS_LOG(LOG_ERR, "Wrong state (no caller?)\n");
1955
                                error_code = JANUS_SIP_ERROR_WRONG_STATE;
1956
                                g_snprintf(error_cause, 512, "Wrong state (no caller?)");
1957
                                goto error;
1958
                        }
1959
                        JANUS_VALIDATE_JSON_OBJECT(root, accept_parameters,
1960
                                error_code, error_cause, TRUE,
1961
                                JANUS_SIP_ERROR_MISSING_ELEMENT, JANUS_SIP_ERROR_INVALID_ELEMENT);
1962
                        if(error_code != 0)
1963
                                goto error;
1964
                        json_t *srtp = json_object_get(root, "srtp");
1965
                        gboolean answer_srtp = FALSE;
1966
                        if(srtp) {
1967
                                const char *srtp_text = json_string_value(srtp);
1968
                                if(!strcasecmp(srtp_text, "sdes_optional")) {
1969
                                        /* Negotiate SDES, but make it optional */
1970
                                        answer_srtp = TRUE;
1971
                                } else if(!strcasecmp(srtp_text, "sdes_mandatory")) {
1972
                                        /* Negotiate SDES, and require it */
1973
                                        answer_srtp = TRUE;
1974
                                        session->media.require_srtp = TRUE;
1975
                                } else {
1976
                                        JANUS_LOG(LOG_ERR, "Invalid element (srtp can only be sdes_optional or sdes_mandatory)\n");
1977
                                        error_code = JANUS_SIP_ERROR_INVALID_ELEMENT;
1978
                                        g_snprintf(error_cause, 512, "Invalid element (srtp can only be sdes_optional or sdes_mandatory)");
1979
                                        goto error;
1980
                                }
1981
                        }
1982
                        if(session->media.require_srtp && !session->media.has_srtp_remote) {
1983
                                JANUS_LOG(LOG_ERR, "Can't accept the call: SDES-SRTP required, but caller didn't offer it\n");
1984
                                error_code = JANUS_SIP_ERROR_TOO_STRICT;
1985
                                g_snprintf(error_cause, 512, "Can't accept the call: SDES-SRTP required, but caller didn't offer it");
1986
                                goto error;
1987
                        }
1988
                        answer_srtp = answer_srtp || session->media.has_srtp_remote;
1989
                        /* Any SDP to handle? if not, something's wrong */
1990
                        const char *msg_sdp_type = json_string_value(json_object_get(msg->jsep, "type"));
1991
                        const char *msg_sdp = json_string_value(json_object_get(msg->jsep, "sdp"));
1992
                        if(!msg_sdp) {
1993
                                JANUS_LOG(LOG_ERR, "Missing SDP\n");
1994
                                error_code = JANUS_SIP_ERROR_MISSING_SDP;
1995
                                g_snprintf(error_cause, 512, "Missing SDP");
1996
                                goto error;
1997
                        }
1998
                        /* Accept a call from another peer */
1999
                        JANUS_LOG(LOG_VERB, "We're accepting the call from %s\n", session->callee);
2000
                        JANUS_LOG(LOG_VERB, "This is involving a negotiation (%s) as well:\n%s\n", msg_sdp_type, msg_sdp);
2001
                        session->media.has_srtp_local = answer_srtp;
2002
                        if(answer_srtp) {
2003
                                JANUS_LOG(LOG_VERB, "Going to negotiate SDES-SRTP (%s)...\n", session->media.require_srtp ? "mandatory" : "optional");
2004
                        }
2005
                        /* Parse the SDP we got, manipulate some things, and generate a new one */
2006
                        char sdperror[100];
2007
                        janus_sdp *parsed_sdp = janus_sdp_parse(msg_sdp, sdperror, sizeof(sdperror));
2008
                        if(!parsed_sdp) {
2009
                                JANUS_LOG(LOG_ERR, "Error parsing SDP: %s\n", sdperror);
2010
                                error_code = JANUS_SIP_ERROR_MISSING_SDP;
2011
                                g_snprintf(error_cause, 512, "Error parsing SDP: %s", sdperror);
2012
                                goto error;
2013
                        }
2014
                        /* Allocate RTP ports and merge them with the anonymized SDP */
2015
                        if(strstr(msg_sdp, "m=audio") && !strstr(msg_sdp, "m=audio 0")) {
2016
                                JANUS_LOG(LOG_VERB, "Going to negotiate audio...\n");
2017
                                session->media.has_audio = 1;        /* FIXME Maybe we need a better way to signal this */
2018
                        }
2019
                        if(strstr(msg_sdp, "m=video") && !strstr(msg_sdp, "m=video 0")) {
2020
                                JANUS_LOG(LOG_VERB, "Going to negotiate video...\n");
2021
                                session->media.has_video = 1;        /* FIXME Maybe we need a better way to signal this */
2022
                        }
2023
                        if(janus_sip_allocate_local_ports(session) < 0) {
2024
                                JANUS_LOG(LOG_ERR, "Could not allocate RTP/RTCP ports\n");
2025
                                janus_sdp_free(parsed_sdp);
2026
                                error_code = JANUS_SIP_ERROR_IO_ERROR;
2027
                                g_snprintf(error_cause, 512, "Could not allocate RTP/RTCP ports");
2028
                                goto error;
2029
                        }
2030
                        char *sdp = janus_sip_sdp_manipulate(session, parsed_sdp, TRUE);
2031
                        if(sdp == NULL) {
2032
                                JANUS_LOG(LOG_ERR, "Could not allocate RTP/RTCP ports\n");
2033
                                janus_sdp_free(parsed_sdp);
2034
                                error_code = JANUS_SIP_ERROR_IO_ERROR;
2035
                                g_snprintf(error_cause, 512, "Could not allocate RTP/RTCP ports");
2036
                                goto error;
2037
                        }
2038
                        if(session->media.audio_pt > -1) {
2039
                                session->media.audio_pt_name = janus_get_codec_from_pt(sdp, session->media.audio_pt);
2040
                                JANUS_LOG(LOG_VERB, "Detected audio codec: %d (%s)\n", session->media.audio_pt, session->media.audio_pt_name);
2041
                        }
2042
                        if(session->media.video_pt > -1) {
2043
                                session->media.video_pt_name = janus_get_codec_from_pt(sdp, session->media.video_pt);
2044
                                JANUS_LOG(LOG_VERB, "Detected video codec: %d (%s)\n", session->media.video_pt, session->media.video_pt_name);
2045
                        }
2046
                        /* Take note of the SDP (may be useful for UPDATEs or re-INVITEs) */
2047
                        janus_sdp_free(session->sdp);
2048
                        session->sdp = parsed_sdp;
2049
                        JANUS_LOG(LOG_VERB, "Prepared SDP for 200 OK:\n%s", sdp);
2050
                        /* Also notify event handlers */
2051
                        if(notify_events && gateway->events_is_enabled()) {
2052
                                json_t *info = json_object();
2053
                                json_object_set_new(info, "event", json_string("accepted"));
2054
                                if(session->callid)
2055
                                        json_object_set_new(info, "call-id", json_string(session->callid));
2056
                                gateway->notify_event(&janus_sip_plugin, session->handle, info);
2057
                        }
2058
                        /* Send 200 OK */
2059
                        g_atomic_int_set(&session->hangingup, 0);
2060
                        session->status = janus_sip_call_status_incall;
2061
                        if(session->stack->s_nh_i == NULL) {
2062
                                JANUS_LOG(LOG_WARN, "NUA Handle for 200 OK still null??\n");
2063
                        }
2064
                        nua_respond(session->stack->s_nh_i,
2065
                                200, sip_status_phrase(200),
2066
                                SOATAG_USER_SDP_STR(sdp),
2067
                                NUTAG_AUTOANSWER(0),
2068
                                TAG_END());
2069
                        g_free(sdp);
2070
                        /* Send an ack back */
2071
                        result = json_object();
2072
                        json_object_set_new(result, "event", json_string("accepted"));
2073
                        /* Start the media */
2074
                        session->media.ready = 1;        /* FIXME Maybe we need a better way to signal this */
2075
                        GError *error = NULL;
2076
                        char tname[16];
2077
                        g_snprintf(tname, sizeof(tname), "siprtp %s", session->account.username);
2078
                        g_thread_try_new(tname, janus_sip_relay_thread, session, &error);
2079
                        if(error != NULL) {
2080
                                JANUS_LOG(LOG_ERR, "Got error %d (%s) trying to launch the RTP/RTCP thread...\n", error->code, error->message ? error->message : "??");
2081
                        }
2082
                } else if(!strcasecmp(request_text, "decline")) {
2083
                        /* Reject an incoming call */
2084
                        if(session->status != janus_sip_call_status_invited) {
2085
                                JANUS_LOG(LOG_ERR, "Wrong state (not invited? status=%s)\n", janus_sip_call_status_string(session->status));
2086
                                /* Ignore */
2087
                                janus_sip_message_free(msg);
2088
                                continue;
2089
                                //~ g_snprintf(error_cause, 512, "Wrong state (not in a call?)");
2090
                                //~ goto error;
2091
                        }
2092
                        if(session->callee == NULL) {
2093
                                JANUS_LOG(LOG_ERR, "Wrong state (no callee?)\n");
2094
                                error_code = JANUS_SIP_ERROR_WRONG_STATE;
2095
                                g_snprintf(error_cause, 512, "Wrong state (no callee?)");
2096
                                goto error;
2097
                        }
2098
                        session->status = janus_sip_call_status_closing;
2099
                        if(session->stack->s_nh_i == NULL) {
2100
                                JANUS_LOG(LOG_WARN, "NUA Handle for 200 OK still null??\n");
2101
                        }
2102
                        int response_code = 486;
2103
                        json_t *code_json = json_object_get(root, "code");
2104
                        if (code_json && json_is_integer(code_json))
2105
                                response_code = json_integer_value(code_json);
2106
                        if (response_code <= 399) {
2107
                                JANUS_LOG(LOG_WARN, "Invalid SIP response code specified, using 486 to decline call\n");
2108
                                response_code = 486;
2109
                        }
2110
                        nua_respond(session->stack->s_nh_i, response_code, sip_status_phrase(response_code), TAG_END());
2111
                        /* Also notify event handlers */
2112
                        if(notify_events && gateway->events_is_enabled()) {
2113
                                json_t *info = json_object();
2114
                                json_object_set_new(info, "event", json_string("declined"));
2115
                                json_object_set_new(info, "callee", json_string(session->callee));
2116
                                if(session->callid)
2117
                                        json_object_set_new(info, "call-id", json_string(session->callid));
2118
                                json_object_set_new(info, "code", json_integer(response_code));
2119
                                gateway->notify_event(&janus_sip_plugin, session->handle, info);
2120
                        }
2121
                        g_free(session->callee);
2122
                        session->callee = NULL;
2123
                        /* Notify the operation */
2124
                        result = json_object();
2125
                        json_object_set_new(result, "event", json_string("declining"));
2126
                        json_object_set_new(result, "code", json_integer(response_code));
2127
                } else if(!strcasecmp(request_text, "hangup")) {
2128
                        /* Hangup an ongoing call */
2129
                        if(!(session->status == janus_sip_call_status_inviting || session->status == janus_sip_call_status_incall)) {
2130
                                JANUS_LOG(LOG_ERR, "Wrong state (not in a call? status=%s)\n", janus_sip_call_status_string(session->status));
2131
                                /* Ignore */
2132
                                janus_sip_message_free(msg);
2133
                                continue;
2134
                                //~ g_snprintf(error_cause, 512, "Wrong state (not in a call?)");
2135
                                //~ goto error;
2136
                        }
2137
                        if(session->callee == NULL) {
2138
                                JANUS_LOG(LOG_ERR, "Wrong state (no callee?)\n");
2139
                                error_code = JANUS_SIP_ERROR_WRONG_STATE;
2140
                                g_snprintf(error_cause, 512, "Wrong state (no callee?)");
2141
                                goto error;
2142
                        }
2143
                        session->status = janus_sip_call_status_closing;
2144
                        nua_bye(session->stack->s_nh_i, TAG_END());
2145
                        g_free(session->callee);
2146
                        session->callee = NULL;
2147
                        /* Notify the operation */
2148
                        result = json_object();
2149
                        json_object_set_new(result, "event", json_string("hangingup"));
2150
                } else if(!strcasecmp(request_text, "recording")) {
2151
                        /* Start or stop recording */
2152
                        if(!(session->status == janus_sip_call_status_inviting || session->status == janus_sip_call_status_incall)) {
2153
                                JANUS_LOG(LOG_ERR, "Wrong state (not in a call? status=%s)\n", janus_sip_call_status_string(session->status));
2154
                                g_snprintf(error_cause, 512, "Wrong state (not in a call?)");
2155
                                goto error;
2156
                        }
2157
                        if(session->callee == NULL) {
2158
                                JANUS_LOG(LOG_ERR, "Wrong state (no callee?)\n");
2159
                                error_code = JANUS_SIP_ERROR_WRONG_STATE;
2160
                                g_snprintf(error_cause, 512, "Wrong state (no callee?)");
2161
                                goto error;
2162
                        }
2163
                        JANUS_VALIDATE_JSON_OBJECT(root, recording_parameters,
2164
                                error_code, error_cause, TRUE,
2165
                                JANUS_SIP_ERROR_MISSING_ELEMENT, JANUS_SIP_ERROR_INVALID_ELEMENT);
2166
                        if(error_code != 0)
2167
                                goto error;
2168
                        json_t *action = json_object_get(root, "action");
2169
                        const char *action_text = json_string_value(action);
2170
                        if(strcasecmp(action_text, "start") && strcasecmp(action_text, "stop")) {
2171
                                JANUS_LOG(LOG_ERR, "Invalid action (should be start|stop)\n");
2172
                                error_code = JANUS_SIP_ERROR_INVALID_ELEMENT;
2173
                                g_snprintf(error_cause, 512, "Invalid action (should be start|stop)");
2174
                                goto error;
2175
                        }
2176
                        gboolean record_audio = FALSE, record_video = FALSE,        /* No media is recorded by default */
2177
                                record_peer_audio = FALSE, record_peer_video = FALSE;
2178
                        json_t *audio = json_object_get(root, "audio");
2179
                        record_audio = audio ? json_is_true(audio) : FALSE;
2180
                        json_t *video = json_object_get(root, "video");
2181
                        record_video = video ? json_is_true(video) : FALSE;
2182
                        json_t *peer_audio = json_object_get(root, "peer_audio");
2183
                        record_peer_audio = peer_audio ? json_is_true(peer_audio) : FALSE;
2184
                        json_t *peer_video = json_object_get(root, "peer_video");
2185
                        record_peer_video = peer_video ? json_is_true(peer_video) : FALSE;
2186
                        if(!record_audio && !record_video && !record_peer_audio && !record_peer_video) {
2187
                                JANUS_LOG(LOG_ERR, "Invalid request (at least one of audio, video, peer_audio and peer_video should be true)\n");
2188
                                error_code = JANUS_SIP_ERROR_RECORDING_ERROR;
2189
                                g_snprintf(error_cause, 512, "Invalid request (at least one of audio, video, peer_audio and peer_video should be true)");
2190
                                goto error;
2191
                        }
2192
                        json_t *recfile = json_object_get(root, "filename");
2193
                        const char *recording_base = json_string_value(recfile);
2194
                        janus_mutex_lock(&session->rec_mutex);
2195
                        if(!strcasecmp(action_text, "start")) {
2196
                                /* Start recording something */
2197
                                char filename[255];
2198
                                gint64 now = janus_get_real_time();
2199
                                if(record_peer_audio || record_peer_video) {
2200
                                        JANUS_LOG(LOG_INFO, "Starting recording of peer's %s (user %s, call %s)\n",
2201
                                                (record_peer_audio && record_peer_video ? "audio and video" : (record_peer_audio ? "audio" : "video")),
2202
                                                session->account.username, session->transaction);
2203
                                        /* Start recording this peer's audio and/or video */
2204
                                        if(record_peer_audio) {
2205
                                                memset(filename, 0, 255);
2206
                                                if(recording_base) {
2207
                                                        /* Use the filename and path we have been provided */
2208
                                                        g_snprintf(filename, 255, "%s-peer-audio", recording_base);
2209
                                                        /* FIXME This only works if offer/answer happened */
2210
                                                        session->arc_peer = janus_recorder_create(NULL, session->media.audio_pt_name, filename);
2211
                                                        if(session->arc_peer == NULL) {
2212
                                                                /* FIXME We should notify the fact the recorder could not be created */
2213
                                                                JANUS_LOG(LOG_ERR, "Couldn't open an audio recording file for this peer!\n");
2214
                                                        }
2215
                                                } else {
2216
                                                        /* Build a filename */
2217
                                                        g_snprintf(filename, 255, "sip-%s-%s-%"SCNi64"-peer-audio",
2218
                                                                session->account.username ? session->account.username : "unknown",
2219
                                                                session->transaction ? session->transaction : "unknown",
2220
                                                                now);
2221
                                                        /* FIXME This only works if offer/answer happened */
2222
                                                        session->arc_peer = janus_recorder_create(NULL, session->media.audio_pt_name, filename);
2223
                                                        if(session->arc_peer == NULL) {
2224
                                                                /* FIXME We should notify the fact the recorder could not be created */
2225
                                                                JANUS_LOG(LOG_ERR, "Couldn't open an audio recording file for this peer!\n");
2226
                                                        }
2227
                                                }
2228
                                        }
2229
                                        if(record_peer_video) {
2230
                                                memset(filename, 0, 255);
2231
                                                if(recording_base) {
2232
                                                        /* Use the filename and path we have been provided */
2233
                                                        g_snprintf(filename, 255, "%s-peer-video", recording_base);
2234
                                                        /* FIXME This only works if offer/answer happened */
2235
                                                        session->vrc_peer = janus_recorder_create(NULL, session->media.video_pt_name, filename);
2236
                                                        if(session->vrc_peer == NULL) {
2237
                                                                /* FIXME We should notify the fact the recorder could not be created */
2238
                                                                JANUS_LOG(LOG_ERR, "Couldn't open an video recording file for this peer!\n");
2239
                                                        }
2240
                                                } else {
2241
                                                        /* Build a filename */
2242
                                                        g_snprintf(filename, 255, "sip-%s-%s-%"SCNi64"-peer-video",
2243
                                                                session->account.username ? session->account.username : "unknown",
2244
                                                                session->transaction ? session->transaction : "unknown",
2245
                                                                now);
2246
                                                        /* FIXME This only works if offer/answer happened */
2247
                                                        session->vrc_peer = janus_recorder_create(NULL, session->media.video_pt_name, filename);
2248
                                                        if(session->vrc_peer == NULL) {
2249
                                                                /* FIXME We should notify the fact the recorder could not be created */
2250
                                                                JANUS_LOG(LOG_ERR, "Couldn't open an video recording file for this peer!\n");
2251
                                                        }
2252
                                                }
2253
                                                /* TODO We should send a FIR/PLI to this peer... */
2254
                                        }
2255
                                }
2256
                                if(record_audio || record_video) {
2257
                                        /* Start recording the user's audio and/or video */
2258
                                        JANUS_LOG(LOG_INFO, "Starting recording of user's %s (user %s, call %s)\n",
2259
                                                (record_audio && record_video ? "audio and video" : (record_audio ? "audio" : "video")),
2260
                                                session->account.username, session->transaction);
2261
                                        if(record_audio) {
2262
                                                memset(filename, 0, 255);
2263
                                                if(recording_base) {
2264
                                                        /* Use the filename and path we have been provided */
2265
                                                        g_snprintf(filename, 255, "%s-user-audio", recording_base);
2266
                                                        /* FIXME This only works if offer/answer happened */
2267
                                                        session->arc = janus_recorder_create(NULL, session->media.audio_pt_name, filename);
2268
                                                        if(session->arc == NULL) {
2269
                                                                /* FIXME We should notify the fact the recorder could not be created */
2270
                                                                JANUS_LOG(LOG_ERR, "Couldn't open an audio recording file for this peer!\n");
2271
                                                        }
2272
                                                } else {
2273
                                                        /* Build a filename */
2274
                                                        g_snprintf(filename, 255, "sip-%s-%s-%"SCNi64"-own-audio",
2275
                                                                session->account.username ? session->account.username : "unknown",
2276
                                                                session->transaction ? session->transaction : "unknown",
2277
                                                                now);
2278
                                                        /* FIXME This only works if offer/answer happened */
2279
                                                        session->arc = janus_recorder_create(NULL, session->media.audio_pt_name, filename);
2280
                                                        if(session->arc == NULL) {
2281
                                                                /* FIXME We should notify the fact the recorder could not be created */
2282
                                                                JANUS_LOG(LOG_ERR, "Couldn't open an audio recording file for this peer!\n");
2283
                                                        }
2284
                                                }
2285
                                        }
2286
                                        if(record_video) {
2287
                                                memset(filename, 0, 255);
2288
                                                if(recording_base) {
2289
                                                        /* Use the filename and path we have been provided */
2290
                                                        g_snprintf(filename, 255, "%s-user-video", recording_base);
2291
                                                        /* FIXME This only works if offer/answer happened */
2292
                                                        session->vrc = janus_recorder_create(NULL, session->media.video_pt_name, filename);
2293
                                                        if(session->vrc == NULL) {
2294
                                                                /* FIXME We should notify the fact the recorder could not be created */
2295
                                                                JANUS_LOG(LOG_ERR, "Couldn't open an video recording file for this user!\n");
2296
                                                        }
2297
                                                } else {
2298
                                                        /* Build a filename */
2299
                                                        g_snprintf(filename, 255, "sip-%s-%s-%"SCNi64"-own-video",
2300
                                                                session->account.username ? session->account.username : "unknown",
2301
                                                                session->transaction ? session->transaction : "unknown",
2302
                                                                now);
2303
                                                        /* FIXME This only works if offer/answer happened */
2304
                                                        session->vrc = janus_recorder_create(NULL, session->media.video_pt_name, filename);
2305
                                                        if(session->vrc == NULL) {
2306
                                                                /* FIXME We should notify the fact the recorder could not be created */
2307
                                                                JANUS_LOG(LOG_ERR, "Couldn't open an video recording file for this user!\n");
2308
                                                        }
2309
                                                }
2310
                                                /* Send a PLI */
2311
                                                JANUS_LOG(LOG_VERB, "Recording video, sending a PLI to kickstart it\n");
2312
                                                char buf[12];
2313
                                                memset(buf, 0, 12);
2314
                                                janus_rtcp_pli((char *)&buf, 12);
2315
                                                gateway->relay_rtcp(session->handle, 1, buf, 12);
2316
                                        }
2317
                                }
2318
                        } else {
2319
                                /* Stop recording something: notice that this never returns an error, even when we were not recording anything */
2320
                                if(record_audio) {
2321
                                        if(session->arc) {
2322
                                                janus_recorder_close(session->arc);
2323
                                                JANUS_LOG(LOG_INFO, "Closed user's audio recording %s\n", session->arc->filename ? session->arc->filename : "??");
2324
                                                janus_recorder_free(session->arc);
2325
                                        }
2326
                                        session->arc = NULL;
2327
                                }
2328
                                if(record_video) {
2329
                                        if(session->vrc) {
2330
                                                janus_recorder_close(session->vrc);
2331
                                                JANUS_LOG(LOG_INFO, "Closed user's video recording %s\n", session->vrc->filename ? session->vrc->filename : "??");
2332
                                                janus_recorder_free(session->vrc);
2333
                                        }
2334
                                        session->vrc = NULL;
2335
                                }
2336
                                if(record_peer_audio) {
2337
                                        if(session->arc_peer) {
2338
                                                janus_recorder_close(session->arc_peer);
2339
                                                JANUS_LOG(LOG_INFO, "Closed peer's audio recording %s\n", session->arc_peer->filename ? session->arc_peer->filename : "??");
2340
                                                janus_recorder_free(session->arc_peer);
2341
                                        }
2342
                                        session->arc_peer = NULL;
2343
                                }
2344
                                if(record_peer_video) {
2345
                                        if(session->vrc_peer) {
2346
                                                janus_recorder_close(session->vrc_peer);
2347
                                                JANUS_LOG(LOG_INFO, "Closed peer's video recording %s\n", session->vrc_peer->filename ? session->vrc_peer->filename : "??");
2348
                                                janus_recorder_free(session->vrc_peer);
2349
                                        }
2350
                                        session->vrc_peer = NULL;
2351
                                }
2352
                        }
2353
                        janus_mutex_unlock(&session->rec_mutex);
2354
                        /* Notify the result */
2355
                        result = json_object();
2356
                        json_object_set_new(result, "event", json_string("recordingupdated"));
2357
                } else if(!strcasecmp(request_text, "dtmf_info")) {
2358
                        /* Send DMTF tones using SIP INFO
2359
                         * (https://tools.ietf.org/html/draft-kaplan-dispatch-info-dtmf-package-00)
2360
                         */
2361
                        if(!(session->status == janus_sip_call_status_inviting || session->status == janus_sip_call_status_incall)) {
2362
                                JANUS_LOG(LOG_ERR, "Wrong state (not in a call? status=%s)\n", janus_sip_call_status_string(session->status));
2363
                                g_snprintf(error_cause, 512, "Wrong state (not in a call?)");
2364
                                goto error;
2365
                        }
2366
                        if(session->callee == NULL) {
2367
                                JANUS_LOG(LOG_ERR, "Wrong state (no callee?)\n");
2368
                                error_code = JANUS_SIP_ERROR_WRONG_STATE;
2369
                                g_snprintf(error_cause, 512, "Wrong state (no callee?)");
2370
                                goto error;
2371
                        }
2372
                        JANUS_VALIDATE_JSON_OBJECT(root, dtmf_info_parameters,
2373
                                error_code, error_cause, TRUE,
2374
                                JANUS_SIP_ERROR_MISSING_ELEMENT, JANUS_SIP_ERROR_INVALID_ELEMENT);
2375
                        if(error_code != 0)
2376
                                goto error;
2377
                        json_t *digit = json_object_get(root, "digit");
2378
                        const char *digit_text = json_string_value(digit);
2379
                        if(strlen(digit_text) != 1) {
2380
                                JANUS_LOG(LOG_ERR, "Invalid element (digit should be one character))\n");
2381
                                error_code = JANUS_SIP_ERROR_INVALID_ELEMENT;
2382
                                g_snprintf(error_cause, 512, "Invalid element (digit should be one character)");
2383
                                goto error;
2384
                        }
2385
                        int duration_ms = 0;
2386
                        json_t *duration = json_object_get(root, "duration");
2387
                        duration_ms = duration ? json_integer_value(duration) : 0;
2388
                        if (duration_ms <= 0 || duration_ms > 5000) {
2389
                                duration_ms = 160; /* default value */
2390
                        }
2391

    
2392
                        char payload[64];
2393
                        g_snprintf(payload, sizeof(payload), "Signal=%s\r\nDuration=%d", digit_text, duration_ms);
2394
                        nua_info(session->stack->s_nh_i,
2395
                                SIPTAG_CONTENT_TYPE_STR("application/dtmf-relay"),
2396
                                SIPTAG_PAYLOAD_STR(payload),
2397
                                TAG_END());
2398
                } else {
2399
                        JANUS_LOG(LOG_ERR, "Unknown request (%s)\n", request_text);
2400
                        error_code = JANUS_SIP_ERROR_INVALID_REQUEST;
2401
                        g_snprintf(error_cause, 512, "Unknown request (%s)", request_text);
2402
                        goto error;
2403
                }
2404

    
2405
                /* Prepare JSON event */
2406
                json_t *event = json_object();
2407
                json_object_set_new(event, "sip", json_string("event"));
2408
                if(result != NULL)
2409
                        json_object_set_new(event, "result", result);
2410
                int ret = gateway->push_event(msg->handle, &janus_sip_plugin, msg->transaction, event, NULL);
2411
                JANUS_LOG(LOG_VERB, "  >> Pushing event: %d (%s)\n", ret, janus_get_api_error(ret));
2412
                json_decref(event);
2413
                janus_sip_message_free(msg);
2414
                continue;
2415

    
2416
error:
2417
                {
2418
                        /* Prepare JSON error event */
2419
                        json_t *event = json_object();
2420
                        json_object_set_new(event, "sip", json_string("event"));
2421
                        json_object_set_new(event, "error_code", json_integer(error_code));
2422
                        json_object_set_new(event, "error", json_string(error_cause));
2423
                        int ret = gateway->push_event(msg->handle, &janus_sip_plugin, msg->transaction, event, NULL);
2424
                        JANUS_LOG(LOG_VERB, "  >> Pushing event: %d (%s)\n", ret, janus_get_api_error(ret));
2425
                        json_decref(event);
2426
                        janus_sip_message_free(msg);
2427
                }
2428
        }
2429
        JANUS_LOG(LOG_VERB, "Leaving SIP handler thread\n");
2430
        return NULL;
2431
}
2432

    
2433

    
2434
/* Sofia callbacks */
2435
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[])
2436
{
2437
        janus_sip_session *session = (janus_sip_session *)magic;
2438
        ssip_t *ssip = session->stack;
2439

    
2440
        /* Notify event handlers about the content of the whole incoming SIP message, if any */
2441
        if(gateway->events_is_enabled() && ssip) {
2442
                /* Print the incoming message */
2443
                size_t msg_size = 0;
2444
                msg_t* msg = nua_current_request(nua);
2445
                if(msg) {
2446
                        char *msg_str = msg_as_string(ssip->s_home, msg, NULL, 0, &msg_size);
2447
                        json_t *info = json_object();
2448
                        json_object_set_new(info, "event", json_string("sip-in"));
2449
                        json_object_set_new(info, "sip", json_string(msg_str));
2450
                        gateway->notify_event(&janus_sip_plugin, session->handle, info);
2451
                }
2452
        }
2453

    
2454
        switch (event) {
2455
        /* Status or Error Indications */
2456
                case nua_i_active:
2457
                        JANUS_LOG(LOG_VERB, "[%s][%s]: %d %s\n", session->account.username, nua_event_name(event), status, phrase ? phrase : "??");
2458
                        break;
2459
                case nua_i_error:
2460
                        JANUS_LOG(LOG_VERB, "[%s][%s]: %d %s\n", session->account.username, nua_event_name(event), status, phrase ? phrase : "??");
2461
                        break;
2462
                case nua_i_fork:
2463
                        JANUS_LOG(LOG_VERB, "[%s][%s]: %d %s\n", session->account.username, nua_event_name(event), status, phrase ? phrase : "??");
2464
                        break;
2465
                case nua_i_media_error:
2466
                        JANUS_LOG(LOG_VERB, "[%s][%s]: %d %s\n", session->account.username, nua_event_name(event), status, phrase ? phrase : "??");
2467
                        break;
2468
                case nua_i_subscription:
2469
                        JANUS_LOG(LOG_VERB, "[%s][%s]: %d %s\n", session->account.username, nua_event_name(event), status, phrase ? phrase : "??");
2470
                        break;
2471
                case nua_i_state:
2472
                        JANUS_LOG(LOG_VERB, "[%s][%s]: %d %s\n", session->account.username, nua_event_name(event), status, phrase ? phrase : "??");
2473
                        tagi_t const *ti = tl_find(tags, nutag_callstate);
2474
                        enum nua_callstate callstate = ti ? ti->t_value : -1;
2475
                        /* There are several call states, but we care about the terminated state in order to send the 'hangup' event
2476
                         * and the proceeding state in order to send the 'proceeding' event so the client can play a ringback tone for
2477
                         * the user since we don't send early media. (assuming this is the right session, of course).
2478
                         * http://sofia-sip.sourceforge.net/refdocs/nua/nua__tag_8h.html#a516dc237722dc8ca4f4aa3524b2b444b
2479
                         */
2480
                        if (callstate == nua_callstate_proceeding &&
2481
                                    (session->stack->s_nh_i == nh || session->stack->s_nh_i == NULL)) {
2482
                                json_t *call = json_object();
2483
                                json_object_set_new(call, "sip", json_string("event"));
2484
                                json_t *calling = json_object();
2485
                                json_object_set_new(calling, "event", json_string("proceeding"));
2486
                                json_object_set_new(calling, "code", json_integer(status));
2487
                                json_object_set_new(call, "result", calling);
2488
                                int ret = gateway->push_event(session->handle, &janus_sip_plugin, session->transaction, call, NULL);
2489
                                JANUS_LOG(LOG_VERB, "  >> Pushing event: %d (%s)\n", ret, janus_get_api_error(ret));
2490
                                json_decref(call);
2491
                                /* Also notify event handlers */
2492
                                if(notify_events && gateway->events_is_enabled()) {
2493
                                        json_t *info = json_object();
2494
                                        json_object_set_new(info, "event", json_string("proceeding"));
2495
                                        if(session->callid)
2496
                                                json_object_set_new(info, "call-id", json_string(session->callid));
2497
                                        json_object_set_new(info, "code", json_integer(status));
2498
                                        gateway->notify_event(&janus_sip_plugin, session->handle, info);
2499
                                }
2500
                        } else if(callstate == nua_callstate_terminated &&
2501
                                        (session->stack->s_nh_i == nh || session->stack->s_nh_i == NULL)) {
2502
                                session->status = janus_sip_call_status_idle;
2503
                                session->stack->s_nh_i = NULL;
2504
                                json_t *call = json_object();
2505
                                json_object_set_new(call, "sip", json_string("event"));
2506
                                json_t *calling = json_object();
2507
                                json_object_set_new(calling, "event", json_string("hangup"));
2508
                                json_object_set_new(calling, "code", json_integer(status));
2509
                                json_object_set_new(calling, "reason", json_string(phrase ? phrase : ""));
2510
                                json_object_set_new(call, "result", calling);
2511
                                int ret = gateway->push_event(session->handle, &janus_sip_plugin, session->transaction, call, NULL);
2512
                                JANUS_LOG(LOG_VERB, "  >> Pushing event: %d (%s)\n", ret, janus_get_api_error(ret));
2513
                                json_decref(call);
2514
                                /* Also notify event handlers */
2515
                                if(notify_events && gateway->events_is_enabled()) {
2516
                                        json_t *info = json_object();
2517
                                        json_object_set_new(info, "event", json_string("hangup"));
2518
                                        if(session->callid)
2519
                                                json_object_set_new(info, "call-id", json_string(session->callid));
2520
                                        json_object_set_new(info, "code", json_integer(status));
2521
                                        if(phrase)
2522
                                                json_object_set_new(info, "reason", json_string(phrase));
2523
                                        gateway->notify_event(&janus_sip_plugin, session->handle, info);
2524
                                }
2525
                                /* Get rid of any PeerConnection that may have been set up */
2526
                                if(session->callid)
2527
                                        g_hash_table_remove(callids, session->callid);
2528
                                g_free(session->callid);
2529
                                session->callid = NULL;
2530
                                g_free(session->transaction);
2531
                                session->transaction = NULL;
2532
                                gateway->close_pc(session->handle);
2533
                        }
2534
                        break;
2535
                case nua_i_terminated:
2536
                        JANUS_LOG(LOG_VERB, "[%s][%s]: %d %s\n", session->account.username, nua_event_name(event), status, phrase ? phrase : "??");
2537
                        break;
2538
        /* SIP requests */
2539
                case nua_i_ack:
2540
                        JANUS_LOG(LOG_VERB, "[%s][%s]: %d %s\n", session->account.username, nua_event_name(event), status, phrase ? phrase : "??");
2541
                        break;
2542
                case nua_i_outbound:
2543
                        JANUS_LOG(LOG_VERB, "[%s][%s]: %d %s\n", session->account.username, nua_event_name(event), status, phrase ? phrase : "??");
2544
                        break;
2545
                case nua_i_bye: {
2546
                        JANUS_LOG(LOG_VERB, "[%s][%s]: %d %s\n", session->account.username, nua_event_name(event), status, phrase ? phrase : "??");
2547
                        break;
2548
                }
2549
                case nua_i_cancel: {
2550
                        JANUS_LOG(LOG_VERB, "[%s][%s]: %d %s\n", session->account.username, nua_event_name(event), status, phrase ? phrase : "??");
2551
                        break;
2552
                }
2553
                case nua_i_invite: {
2554
                        JANUS_LOG(LOG_VERB, "[%s][%s]: %d %s\n", session->account.username, nua_event_name(event), status, phrase ? phrase : "??");
2555
                        if(ssip == NULL) {
2556
                                JANUS_LOG(LOG_ERR, "\tInvalid SIP stack\n");
2557
                                nua_respond(nh, 500, sip_status_phrase(500), TAG_END());
2558
                                break;
2559
                        }
2560
                        if(!sip->sip_payload) {
2561
                                JANUS_LOG(LOG_WARN,"\tReceived re-invite without SDP - responding 200 OK\n");
2562
                                nua_respond(nh, 200, sip_status_phrase(200), TAG_END());
2563
                                break;
2564
                        }
2565
                        char sdperror[100];
2566
                        janus_sdp *sdp = janus_sdp_parse(sip->sip_payload->pl_data, sdperror, sizeof(sdperror));
2567
                        if(!sdp) {
2568
                                JANUS_LOG(LOG_ERR, "\tError parsing SDP! %s\n", sdperror);
2569
                                nua_respond(nh, 488, sip_status_phrase(488), TAG_END());
2570
                                break;
2571
                        }
2572
                        gboolean reinvite = FALSE;
2573
                        if(session->stack->s_nh_i != NULL) {
2574
                                if(session->stack->s_nh_i == nh) {
2575
                                        /* re-INVITE, we'll check what changed later */
2576
                                        reinvite = TRUE;
2577
                                        JANUS_LOG(LOG_VERB, "Got a re-INVITE...\n");
2578
                                } else if(session->status >= janus_sip_call_status_inviting) {
2579
                                        /* Busy with another call */
2580
                                        JANUS_LOG(LOG_VERB, "\tAlready in a call (busy, status=%s)\n", janus_sip_call_status_string(session->status));
2581
                                        nua_respond(nh, 486, sip_status_phrase(486), TAG_END());
2582
                                        /* Notify the web app about the missed invite */
2583
                                        json_t *missed = json_object();
2584
                                        json_object_set_new(missed, "sip", json_string("event"));
2585
                                        json_t *result = json_object();
2586
                                        json_object_set_new(result, "event", json_string("missed_call"));
2587
                                        char *caller_text = url_as_string(session->stack->s_home, sip->sip_from->a_url);
2588
                                        json_object_set_new(result, "caller", json_string(caller_text));
2589
                                        su_free(session->stack->s_home, caller_text);
2590
                                        if (sip->sip_from && sip->sip_from->a_display) {
2591
                                                json_object_set_new(result, "displayname", json_string(sip->sip_from->a_display));
2592
                                        }
2593
                                        json_object_set_new(missed, "result", result);
2594
                                        int ret = gateway->push_event(session->handle, &janus_sip_plugin, session->transaction, missed, NULL);
2595
                                        JANUS_LOG(LOG_VERB, "  >> Pushing event to peer: %d (%s)\n", ret, janus_get_api_error(ret));
2596
                                        json_decref(missed);
2597
                                        /* Also notify event handlers */
2598
                                        if(notify_events && gateway->events_is_enabled()) {
2599
                                                json_t *info = json_object();
2600
                                                json_object_set_new(info, "event", json_string("missed_call"));
2601
                                                json_object_set_new(info, "caller", json_string(caller_text));
2602
                                                gateway->notify_event(&janus_sip_plugin, session->handle, info);
2603
                                        }
2604
                                        break;
2605
                                }
2606
                        }
2607
                        if(!reinvite) {
2608
                                /* New incoming call */
2609
                                session->callee = g_strdup(url_as_string(session->stack->s_home, sip->sip_from->a_url));
2610
                                session->callid = sip && sip->sip_call_id ? g_strdup(sip->sip_call_id->i_id) : NULL;
2611
                                if(session->callid)
2612
                                        g_hash_table_insert(callids, session->callid, session);
2613
                                session->status = janus_sip_call_status_invited;
2614
                                /* Clean up SRTP stuff from before first, in case it's still needed */
2615
                                janus_sip_srtp_cleanup(session);
2616
                        }
2617
                        /* Parse SDP */
2618
                        JANUS_LOG(LOG_VERB, "Someone is %s a call:\n%s",
2619
                                reinvite ? "updating" : "inviting us in",
2620
                                sip->sip_payload->pl_data);
2621
                        gboolean changed = FALSE;
2622
                        janus_sip_sdp_process(session, sdp, FALSE, reinvite, &changed);
2623
                        /* Check if offer has neither audio nor video, fail with 488 */
2624
                        if (!session->media.has_audio && !session->media.has_video) {
2625
                                nua_respond(nh, 488, sip_status_phrase(488), TAG_END());
2626
                                janus_sdp_free(sdp);
2627
                                break;
2628
                        }
2629
                        /* Also fail with 488 if there's no remote IP address that can be used for RTP */
2630
                        if (!session->media.remote_ip) {
2631
                                nua_respond(nh, 488, sip_status_phrase(488), TAG_END());
2632
                                janus_sdp_free(sdp);
2633
                                break;
2634
                        }
2635
                        if(reinvite) {
2636
                                /* No need to involve the browser: we reply ourselves */
2637
                                nua_respond(nh, 200, sip_status_phrase(200), TAG_END());
2638
                                janus_sdp_free(sdp);
2639
                                break;
2640
                        }
2641
                        /* Send SDP to the browser */
2642
                        char *fixed_sdp = g_strdup(sip->sip_payload->pl_data);
2643
                        json_t *jsep = json_pack("{ssss}", "type", "offer", "sdp", fixed_sdp);
2644
                        json_t *call = json_object();
2645
                        json_object_set_new(call, "sip", json_string("event"));
2646
                        json_t *calling = json_object();
2647
                        json_object_set_new(calling, "event", json_string("incomingcall"));
2648
                        json_object_set_new(calling, "username", json_string(session->callee));
2649
                        if(sip->sip_from && sip->sip_from->a_display) {
2650
                                json_object_set_new(calling, "displayname", json_string(sip->sip_from->a_display));
2651
                        }
2652
                        if(session->media.has_srtp_remote) {
2653
                                /* FIXME Maybe a true/false instead? */
2654
                                json_object_set_new(calling, "srtp", json_string(session->media.require_srtp ? "sdes_mandatory" : "sdes_optional"));
2655
                        }
2656
                        json_object_set_new(call, "result", calling);
2657
                        int ret = gateway->push_event(session->handle, &janus_sip_plugin, session->transaction, call, jsep);
2658
                        JANUS_LOG(LOG_VERB, "  >> Pushing event to peer: %d (%s)\n", ret, janus_get_api_error(ret));
2659
                        json_decref(call);
2660
                        json_decref(jsep);
2661
                        g_free(fixed_sdp);
2662
                        janus_sdp_free(sdp);
2663
                        /* Also notify event handlers */
2664
                        if(notify_events && gateway->events_is_enabled()) {
2665
                                json_t *info = json_object();
2666
                                json_object_set_new(info, "event", json_string("incomingcall"));
2667
                                if(session->callid)
2668
                                        json_object_set_new(info, "call-id", json_string(session->callid));
2669
                                json_object_set_new(info, "username", json_string(session->callee));
2670
                                if(sip->sip_from && sip->sip_from->a_display)
2671
                                        json_object_set_new(info, "displayname", json_string(sip->sip_from->a_display));
2672
                                gateway->notify_event(&janus_sip_plugin, session->handle, info);
2673
                        }
2674
                        /* Send a Ringing back */
2675
                        nua_respond(nh, 180, sip_status_phrase(180), TAG_END());
2676
                        session->stack->s_nh_i = nh;
2677
                        break;
2678
                }
2679
                case nua_i_options:
2680
                        JANUS_LOG(LOG_VERB, "[%s][%s]: %d %s\n", session->account.username, nua_event_name(event), status, phrase ? phrase : "??");
2681
                        /* FIXME Should we handle this message? for now we reply with a 405 Method Not Implemented */
2682
                        nua_respond(nh, 405, sip_status_phrase(405), TAG_END());
2683
                        break;
2684
        /* Responses */
2685
                case nua_r_get_params:
2686
                        JANUS_LOG(LOG_VERB, "[%s][%s]: %d %s\n", session->account.username, nua_event_name(event), status, phrase ? phrase : "??");
2687
                        break;
2688
                case nua_r_set_params:
2689
                        JANUS_LOG(LOG_VERB, "[%s][%s]: %d %s\n", session->account.username, nua_event_name(event), status, phrase ? phrase : "??");
2690
                        break;
2691
                case nua_r_notifier:
2692
                        JANUS_LOG(LOG_VERB, "[%s][%s]: %d %s\n", session->account.username, nua_event_name(event), status, phrase ? phrase : "??");
2693
                        break;
2694
                case nua_r_shutdown:
2695
                        JANUS_LOG(LOG_VERB, "[%s][%s]: %d %s\n", session->account.username, nua_event_name(event), status, phrase ? phrase : "??");
2696
                        if(status < 200 && !g_atomic_int_get(&stopping)) {
2697
                                /* shutdown in progress -> return */
2698
                                break;
2699
                        }
2700
                        if(ssip != NULL) {
2701
                                /* end the event loop. su_root_run() will return */
2702
                                su_root_break(ssip->s_root);
2703
                        }
2704
                        break;
2705
                case nua_r_terminate:
2706
                        JANUS_LOG(LOG_VERB, "[%s][%s]: %d %s\n", session->account.username, nua_event_name(event), status, phrase ? phrase : "??");
2707
                        break;
2708
        /* SIP responses */
2709
                case nua_r_bye:
2710
                        JANUS_LOG(LOG_VERB, "[%s][%s]: %d %s\n", session->account.username, nua_event_name(event), status, phrase ? phrase : "??");
2711
                        break;
2712
                case nua_r_cancel:
2713
                        JANUS_LOG(LOG_VERB, "[%s][%s]: %d %s\n", session->account.username, nua_event_name(event), status, phrase ? phrase : "??");
2714
                        break;
2715
                case nua_r_info:
2716
                        JANUS_LOG(LOG_VERB, "[%s][%s]: %d %s\n", session->account.username, nua_event_name(event), status, phrase ? phrase : "??");
2717
                        break;
2718
                case nua_r_invite: {
2719
                        JANUS_LOG(LOG_VERB, "[%s][%s]: %d %s\n", session->account.username, nua_event_name(event), status, phrase ? phrase : "??");
2720

    
2721
                        if(status < 200) {
2722
                                /* Not ready yet (FIXME May this be pranswer?? we don't handle it yet...) */
2723
                                break;
2724
                        } else if(status == 401 || status == 407) {
2725
                                char auth[256];
2726
                                const char* scheme;
2727
                                const char* realm;
2728
                                if(status == 401) {
2729
                                         /* Get scheme/realm from 401 error */
2730
                                        sip_www_authenticate_t const* www_auth = sip->sip_www_authenticate;
2731
                                        scheme = www_auth->au_scheme;
2732
                                        realm = msg_params_find(www_auth->au_params, "realm=");
2733
                                } else {
2734
                                         /* Get scheme/realm from 407 error, proxy-auth */
2735
                                        sip_proxy_authenticate_t const* proxy_auth = sip->sip_proxy_authenticate;
2736
                                        scheme = proxy_auth->au_scheme;
2737
                                        realm = msg_params_find(proxy_auth->au_params, "realm=");
2738
                                }
2739
                                memset(auth, 0, sizeof(auth));
2740
                                g_snprintf(auth, sizeof(auth), "%s%s:%s:%s:%s%s",
2741
                                        session->account.secret_type == janus_sip_secret_type_hashed ? "HA1+" : "",
2742
                                        scheme,
2743
                                        realm,
2744
                                        session->account.authuser ? session->account.authuser : "null",
2745
                                        session->account.secret_type == janus_sip_secret_type_hashed ? "HA1+" : "",
2746
                                        session->account.secret ? session->account.secret : "null");
2747
                                JANUS_LOG(LOG_VERB, "\t%s\n", auth);
2748
                                /* Authenticate */
2749
                                nua_authenticate(nh,
2750
                                        NUTAG_AUTH(auth),
2751
                                        TAG_END());
2752
                                break;
2753
                        } else if(status >= 400) {
2754
                                break;
2755
                        }
2756
                        if(ssip == NULL) {
2757
                                JANUS_LOG(LOG_ERR, "\tInvalid SIP stack\n");
2758
                                nua_respond(nh, 500, sip_status_phrase(500), TAG_END());
2759
                                break;
2760
                        }
2761
                        char sdperror[100];
2762
                        janus_sdp *sdp = janus_sdp_parse(sip->sip_payload->pl_data, sdperror, sizeof(sdperror));
2763
                        if(!sdp) {
2764
                                JANUS_LOG(LOG_ERR, "\tError parsing SDP! %s\n", sdperror);
2765
                                nua_respond(nh, 488, sip_status_phrase(488), TAG_END());
2766
                                break;
2767
                        }
2768
                        /* Send an ACK, if needed */
2769
                        if(!session->media.autoack) {
2770
                                char *route = sip->sip_record_route ? url_as_string(session->stack->s_home, sip->sip_record_route->r_url) : NULL;
2771
                                JANUS_LOG(LOG_INFO, "Sending ACK (route=%s)\n", route ? route : "none");
2772
                                nua_ack(nh,
2773
                                        TAG_IF(route, NTATAG_DEFAULT_PROXY(route)),
2774
                                        TAG_END());
2775
                        }
2776
                        /* Parse SDP */
2777
                        JANUS_LOG(LOG_VERB, "Peer accepted our call:\n%s", sip->sip_payload->pl_data);
2778
                        session->status = janus_sip_call_status_incall;
2779
                        char *fixed_sdp = g_strdup(sip->sip_payload->pl_data);
2780
                        janus_sip_sdp_process(session, sdp, TRUE, FALSE, NULL);
2781
                        /* If we asked for SRTP and are not getting it, fail */
2782
                        if(session->media.require_srtp && !session->media.has_srtp_remote) {
2783
                                JANUS_LOG(LOG_ERR, "\tWe asked for mandatory SRTP but didn't get any in the reply!\n");
2784
                                janus_sdp_free(sdp);
2785
                                g_free(fixed_sdp);
2786
                                /* Hangup immediately */
2787
                                session->status = janus_sip_call_status_closing;
2788
                                nua_bye(nh, TAG_END());
2789
                                g_free(session->callee);
2790
                                session->callee = NULL;
2791
                                break;
2792
                        }
2793
                        if(!session->media.remote_ip) {
2794
                                /* No remote address parsed? Give up */
2795
                                JANUS_LOG(LOG_ERR, "\tNo remote IP address found for RTP, something's wrong with the SDP!\n");
2796
                                janus_sdp_free(sdp);
2797
                                g_free(fixed_sdp);
2798
                                /* Hangup immediately */
2799
                                session->status = janus_sip_call_status_closing;
2800
                                nua_bye(nh, TAG_END());
2801
                                g_free(session->callee);
2802
                                session->callee = NULL;
2803
                                break;
2804
                        }
2805
                        if(session->media.audio_pt > -1) {
2806
                                session->media.audio_pt_name = janus_get_codec_from_pt(fixed_sdp, session->media.audio_pt);
2807
                                JANUS_LOG(LOG_VERB, "Detected audio codec: %d (%s)\n", session->media.audio_pt, session->media.audio_pt_name);
2808
                        }
2809
                        if(session->media.video_pt > -1) {
2810
                                session->media.video_pt_name = janus_get_codec_from_pt(fixed_sdp, session->media.video_pt);
2811
                                JANUS_LOG(LOG_VERB, "Detected video codec: %d (%s)\n", session->media.video_pt, session->media.video_pt_name);
2812
                        }
2813
                        session->media.ready = 1;        /* FIXME Maybe we need a better way to signal this */
2814
                        GError *error = NULL;
2815
                        char tname[16];
2816
                        g_snprintf(tname, sizeof(tname), "siprtp %s", session->account.username);
2817
                        g_thread_try_new(tname, janus_sip_relay_thread, session, &error);
2818
                        if(error != NULL) {
2819
                                JANUS_LOG(LOG_ERR, "Got error %d (%s) trying to launch the RTP/RTCP thread...\n", error->code, error->message ? error->message : "??");
2820
                        }
2821
                        /* Send SDP to the browser */
2822
                        json_t *jsep = json_pack("{ssss}", "type", "answer", "sdp", fixed_sdp);
2823
                        json_t *call = json_object();
2824
                        json_object_set_new(call, "sip", json_string("event"));
2825
                        json_t *calling = json_object();
2826
                        json_object_set_new(calling, "event", json_string("accepted"));
2827
                        json_object_set_new(calling, "username", json_string(session->callee));
2828
                        json_object_set_new(call, "result", calling);
2829
                        int ret = gateway->push_event(session->handle, &janus_sip_plugin, session->transaction, call, jsep);
2830
                        JANUS_LOG(LOG_VERB, "  >> Pushing event to peer: %d (%s)\n", ret, janus_get_api_error(ret));
2831
                        json_decref(call);
2832
                        json_decref(jsep);
2833
                        g_free(fixed_sdp);
2834
                        janus_sdp_free(sdp);
2835
                        /* Also notify event handlers */
2836
                        if(notify_events && gateway->events_is_enabled()) {
2837
                                json_t *info = json_object();
2838
                                json_object_set_new(info, "event", json_string("accepted"));
2839
                                if(session->callid)
2840
                                        json_object_set_new(info, "call-id", json_string(session->callid));
2841
                                json_object_set_new(info, "username", json_string(session->callee));
2842
                                gateway->notify_event(&janus_sip_plugin, session->handle, info);
2843
                        }
2844
                        break;
2845
                }
2846
                case nua_r_register: {
2847
                        JANUS_LOG(LOG_VERB, "[%s][%s]: %d %s\n", session->account.username, nua_event_name(event), status, phrase ? phrase : "??");
2848
                        if(status == 200) {
2849
                                if(session->account.registration_status < janus_sip_registration_status_registered)
2850
                                        session->account.registration_status = janus_sip_registration_status_registered;
2851
                                JANUS_LOG(LOG_VERB, "Successfully registered\n");
2852
                                /* Notify the browser */
2853
                                json_t *call = json_object();
2854
                                json_object_set_new(call, "sip", json_string("event"));
2855
                                json_t *calling = json_object();
2856
                                json_object_set_new(calling, "event", json_string("registered"));
2857
                                json_object_set_new(calling, "username", json_string(session->account.username));
2858
                                json_object_set_new(calling, "register_sent", json_true());
2859
                                json_object_set_new(call, "result", calling);
2860
                                int ret = gateway->push_event(session->handle, &janus_sip_plugin, session->transaction, call, NULL);
2861
                                JANUS_LOG(LOG_VERB, "  >> Pushing event to peer: %d (%s)\n", ret, janus_get_api_error(ret));
2862
                                json_decref(call);
2863
                                /* Also notify event handlers */
2864
                                if(notify_events && gateway->events_is_enabled()) {
2865
                                        json_t *info = json_object();
2866
                                        json_object_set_new(info, "event", json_string("registered"));
2867
                                        json_object_set_new(info, "identity", json_string(session->account.identity));
2868
                                        if(session->account.proxy)
2869
                                                json_object_set_new(info, "proxy", json_string(session->account.proxy));
2870
                                        gateway->notify_event(&janus_sip_plugin, session->handle, info);
2871
                                }
2872
                        } else if(status == 401) {
2873
                                /* Get scheme/realm from 401 error */
2874
                                sip_www_authenticate_t const* www_auth = sip->sip_www_authenticate;
2875
                                char const* scheme = www_auth->au_scheme;
2876
                                const char* realm = msg_params_find(www_auth->au_params, "realm=");
2877
                                char auth[256];
2878
                                memset(auth, 0, sizeof(auth));
2879
                                g_snprintf(auth, sizeof(auth), "%s%s:%s:%s:%s%s",
2880
                                        session->account.secret_type == janus_sip_secret_type_hashed ? "HA1+" : "",
2881
                                        scheme,
2882
                                        realm,
2883
                                        session->account.authuser ? session->account.authuser : "null",
2884
                                        session->account.secret_type == janus_sip_secret_type_hashed ? "HA1+" : "",
2885
                                        session->account.secret);
2886
                                JANUS_LOG(LOG_VERB, "\t%s\n", auth);
2887
                                /* Authenticate */
2888
                                nua_authenticate(nh,
2889
                                        NUTAG_AUTH(auth),
2890
                                        TAG_END());
2891
                        } else if(status >= 400) {
2892
                                /* Authentication failed? */
2893
                                session->account.registration_status = janus_sip_registration_status_failed;
2894
                                /* Tell the browser... */
2895
                                json_t *event = json_object();
2896
                                json_object_set_new(event, "sip", json_string("event"));
2897
                                json_t *result = json_object();
2898
                                json_object_set_new(result, "event", json_string("registration_failed"));
2899
                                json_object_set_new(result, "code", json_integer(status));
2900
                                json_object_set_new(result, "reason", json_string(phrase ? phrase : ""));
2901
                                json_object_set_new(event, "result", result);
2902
                                int ret = gateway->push_event(session->handle, &janus_sip_plugin, session->transaction, event, NULL);
2903
                                JANUS_LOG(LOG_VERB, "  >> Pushing event to peer: %d (%s)\n", ret, janus_get_api_error(ret));
2904
                                json_decref(event);
2905
                                /* Also notify event handlers */
2906
                                if(notify_events && gateway->events_is_enabled()) {
2907
                                        json_t *info = json_object();
2908
                                        json_object_set_new(info, "event", json_string("registration_failed"));
2909
                                        json_object_set_new(info, "code", json_integer(status));
2910
                                        if(phrase)
2911
                                                json_object_set_new(info, "reason", json_string(phrase ? phrase : ""));
2912
                                        gateway->notify_event(&janus_sip_plugin, session->handle, info);
2913
                                }
2914
                        }
2915
                        break;
2916
                }
2917
                default:
2918
                        /* unknown event -> print out error message */
2919
                        JANUS_LOG(LOG_ERR, "Unknown event %d (%s)\n", event, nua_event_name(event));
2920
                        break;
2921
        }
2922
}
2923

    
2924
void janus_sip_sdp_process(janus_sip_session *session, janus_sdp *sdp, gboolean answer, gboolean update, gboolean *changed) {
2925
        if(!session || !sdp)
2926
                return;
2927
        /* c= */
2928
        if(sdp->c_addr) {
2929
                if(update && strcmp(sdp->c_addr, session->media.remote_ip)) {
2930
                        /* This is an update and an address changed */
2931
                        if(changed)
2932
                                *changed = TRUE;
2933
                }
2934
                g_free(session->media.remote_ip);
2935
                session->media.remote_ip = g_strdup(sdp->c_addr);
2936
        }
2937
        GList *temp = sdp->m_lines;
2938
        while(temp) {
2939
                janus_sdp_mline *m = (janus_sdp_mline *)temp->data;
2940
                session->media.require_srtp = session->media.require_srtp || (m->proto && !strcasecmp(m->proto, "RTP/SAVP"));
2941
                if(m->type == JANUS_SDP_AUDIO) {
2942
                        if(m->port) {
2943
                                if(m->port != session->media.remote_audio_rtp_port) {
2944
                                        /* This is an update and an address changed */
2945
                                        if(changed)
2946
                                                *changed = TRUE;
2947
                                }
2948
                                session->media.has_audio = 1;
2949
                                session->media.remote_audio_rtp_port = m->port;
2950
                                session->media.remote_audio_rtcp_port = m->port+1;        /* FIXME We're assuming RTCP is on the next port */
2951
                                if(m->direction == JANUS_SDP_SENDONLY || m->direction == JANUS_SDP_INACTIVE)
2952
                                        session->media.audio_send = FALSE;
2953
                                else
2954
                                        session->media.audio_send = TRUE;
2955
                        } else {
2956
                                session->media.audio_send = FALSE;
2957
                        }
2958
                } else if(m->type == JANUS_SDP_VIDEO) {
2959
                        if(m->port) {
2960
                                if(m->port != session->media.remote_video_rtp_port) {
2961
                                        /* This is an update and an address changed */
2962
                                        if(changed)
2963
                                                *changed = TRUE;
2964
                                }
2965
                                session->media.has_video = 1;
2966
                                session->media.remote_video_rtp_port = m->port;
2967
                                session->media.remote_video_rtcp_port = m->port+1;        /* FIXME We're assuming RTCP is on the next port */
2968
                                if(m->direction == JANUS_SDP_SENDONLY || m->direction == JANUS_SDP_INACTIVE)
2969
                                        session->media.video_send = FALSE;
2970
                                else
2971
                                        session->media.video_send = TRUE;
2972
                        } else {
2973
                                session->media.video_send = FALSE;
2974
                        }
2975
                } else {
2976
                        JANUS_LOG(LOG_WARN, "Unsupported media line (not audio/video)\n");
2977
                        temp = temp->next;
2978
                        continue;
2979
                }
2980
                if(m->c_addr) {
2981
                        if(update && strcmp(m->c_addr, session->media.remote_ip)) {
2982
                                /* This is an update and an address changed */
2983
                                if(changed)
2984
                                        *changed = TRUE;
2985
                        }
2986
                        g_free(session->media.remote_ip);
2987
                        session->media.remote_ip = g_strdup(m->c_addr);
2988
                }
2989
                if(update) {
2990
                        /* FIXME This is a session update, we only accept changes in IP/ports */
2991
                        temp = temp->next;
2992
                        continue;
2993
                }
2994
                GList *tempA = m->attributes;
2995
                while(tempA) {
2996
                        janus_sdp_attribute *a = (janus_sdp_attribute *)tempA->data;
2997
                        if(a->name) {
2998
                                if(!strcasecmp(a->name, "crypto")) {
2999
                                        if(m->type == JANUS_SDP_AUDIO || m->type == JANUS_SDP_VIDEO) {
3000
                                                gint32 tag = 0;
3001
                                                int suite;
3002
                                                char crypto[81];
3003
                                                /* FIXME inline can be more complex than that, and we're currently only offering SHA1_80 */
3004
                                                int res = sscanf(a->value, "%"SCNi32" AES_CM_128_HMAC_SHA1_%2d inline:%80s",
3005
                                                        &tag, &suite, crypto);
3006
                                                if(res != 3) {
3007
                                                        JANUS_LOG(LOG_WARN, "Failed to parse crypto line, ignoring... %s\n", a->value);
3008
                                                } else {
3009
                                                        gboolean video = (m->type == JANUS_SDP_VIDEO);
3010
                                                        int current_suite = video ? session->media.video_srtp_suite_in : session->media.audio_srtp_suite_in;
3011
                                                        if(current_suite == 0) {
3012
                                                                if(video)
3013
                                                                        session->media.video_srtp_suite_in = suite;
3014
                                                                else
3015
                                                                        session->media.audio_srtp_suite_in = suite;
3016
                                                                janus_sip_srtp_set_remote(session, video, crypto, suite);
3017
                                                                session->media.has_srtp_remote = TRUE;
3018
                                                        } else {
3019
                                                                JANUS_LOG(LOG_WARN, "We already configured a %s crypto context (AES_CM_128_HMAC_SHA1_%d), skipping additional crypto line\n",
3020
                                                                        video ? "video" : "audio", current_suite);
3021
                                                        }
3022
                                                }
3023
                                        }
3024
                                }
3025
                        }
3026
                        tempA = tempA->next;
3027
                }
3028
                if(answer && (m->type == JANUS_SDP_AUDIO || m->type == JANUS_SDP_VIDEO)) {
3029
                        /* Check which codec was negotiated eventually */
3030
                        int pt = -1;
3031
                        if(m->ptypes)
3032
                                pt = GPOINTER_TO_INT(m->ptypes->data);
3033
                        if(pt > -1) {
3034
                                if(m->type == JANUS_SDP_AUDIO) {
3035
                                        session->media.audio_pt = pt;
3036
                                } else {
3037
                                        session->media.video_pt = pt;
3038
                                }
3039
                        }
3040
                }
3041
                temp = temp->next;
3042
        }
3043
        if(changed && *changed) {
3044
                /* Something changed: mark this on the session, so that the thread can update the sockets */
3045
                session->media.updated = TRUE;
3046
                if(session->media.pipefd[1] > 0) {
3047
                        int code = 1;
3048
                        ssize_t res = 0;
3049
                        do {
3050
                                res = write(session->media.pipefd[1], &code, sizeof(int));
3051
                        } while(res == -1 && errno == EINTR);
3052
                }
3053
        }
3054
}
3055

    
3056
char *janus_sip_sdp_manipulate(janus_sip_session *session, janus_sdp *sdp, gboolean answer) {
3057
        if(!session || !session->stack || !sdp)
3058
                return NULL;
3059
        /* Start replacing stuff */
3060
        JANUS_LOG(LOG_VERB, "Setting protocol to %s\n", session->media.require_srtp ? "RTP/SAVP" : "RTP/AVP");
3061
        GList *temp = sdp->m_lines;
3062
        while(temp) {
3063
                janus_sdp_mline *m = (janus_sdp_mline *)temp->data;
3064
                g_free(m->proto);
3065
                m->proto = g_strdup(session->media.require_srtp ? "RTP/SAVP" : "RTP/AVP");
3066
                if(m->type == JANUS_SDP_AUDIO) {
3067
                        m->port = session->media.local_audio_rtp_port;
3068
                        if(session->media.has_srtp_local) {
3069
                                char *crypto = NULL;
3070
                                session->media.audio_srtp_suite_out = 80;
3071
                                janus_sip_srtp_set_local(session, FALSE, &crypto);
3072
                                /* FIXME 32? 80? Both? */
3073
                                janus_sdp_attribute *a = janus_sdp_attribute_create("crypto", "1 AES_CM_128_HMAC_SHA1_80 inline:%s", crypto);
3074
                                g_free(crypto);
3075
                                m->attributes = g_list_append(m->attributes, a);
3076
                        }
3077
                } else if(m->type == JANUS_SDP_VIDEO) {
3078
                        m->port = session->media.local_video_rtp_port;
3079
                        if(session->media.has_srtp_local) {
3080
                                char *crypto = NULL;
3081
                                session->media.audio_srtp_suite_out = 80;
3082
                                janus_sip_srtp_set_local(session, TRUE, &crypto);
3083
                                /* FIXME 32? 80? Both? */
3084
                                janus_sdp_attribute *a = janus_sdp_attribute_create("crypto", "1 AES_CM_128_HMAC_SHA1_80 inline:%s", crypto);
3085
                                g_free(crypto);
3086
                                m->attributes = g_list_append(m->attributes, a);
3087
                        }
3088
                }
3089
                g_free(m->c_addr);
3090
                m->c_addr = g_strdup(local_ip);
3091
                if(answer && (m->type == JANUS_SDP_AUDIO || m->type == JANUS_SDP_VIDEO)) {
3092
                        /* Check which codec was negotiated eventually */
3093
                        int pt = -1;
3094
                        if(m->ptypes)
3095
                                pt = GPOINTER_TO_INT(m->ptypes->data);
3096
                        if(pt > -1) {
3097
                                if(m->type == JANUS_SDP_AUDIO) {
3098
                                        session->media.audio_pt = pt;
3099
                                } else {
3100
                                        session->media.video_pt = pt;
3101
                                }
3102
                        }
3103
                }
3104
                temp = temp->next;
3105
        }
3106
        /* Generate a SDP string out of our changes */
3107
        return janus_sdp_write(sdp);
3108
}
3109

    
3110
/* Bind local RTP/RTCP sockets */
3111
static int janus_sip_allocate_local_ports(janus_sip_session *session) {
3112
        if(session == NULL) {
3113
                JANUS_LOG(LOG_ERR, "Invalid session\n");
3114
                return -1;
3115
        }
3116
        /* Reset status */
3117
        if(session->media.audio_rtp_fd != -1) {
3118
                close(session->media.audio_rtp_fd);
3119
                session->media.audio_rtp_fd = -1;
3120
        }
3121
        if(session->media.audio_rtcp_fd != -1) {
3122
                close(session->media.audio_rtcp_fd);
3123
                session->media.audio_rtcp_fd = -1;
3124
        }
3125
        session->media.local_audio_rtp_port = 0;
3126
        session->media.local_audio_rtcp_port = 0;
3127
        session->media.audio_ssrc = 0;
3128
        if(session->media.video_rtp_fd != -1) {
3129
                close(session->media.video_rtp_fd);
3130
                session->media.video_rtp_fd = -1;
3131
        }
3132
        if(session->media.video_rtcp_fd != -1) {
3133
                close(session->media.video_rtcp_fd);
3134
                session->media.video_rtcp_fd = -1;
3135
        }
3136
        session->media.local_video_rtp_port = 0;
3137
        session->media.local_video_rtcp_port = 0;
3138
        session->media.video_ssrc = 0;
3139
        if(session->media.pipefd[0] > 0) {
3140
                close(session->media.pipefd[0]);
3141
                session->media.pipefd[0] = -1;
3142
        }
3143
        if(session->media.pipefd[1] > 0) {
3144
                close(session->media.pipefd[1]);
3145
                session->media.pipefd[1] = -1;
3146
        }
3147
        /* Start */
3148
        int attempts = 100;        /* FIXME Don't retry forever */
3149
        if(session->media.has_audio) {
3150
                JANUS_LOG(LOG_VERB, "Allocating audio ports:\n");
3151
                struct sockaddr_in audio_rtp_address, audio_rtcp_address;
3152
                while(session->media.local_audio_rtp_port == 0 || session->media.local_audio_rtcp_port == 0) {
3153
                        if(attempts == 0)        /* Too many failures */
3154
                                return -1;
3155
                        if(session->media.audio_rtp_fd == -1) {
3156
                                session->media.audio_rtp_fd = socket(AF_INET, SOCK_DGRAM, 0);
3157
                        }
3158
                        if(session->media.audio_rtcp_fd == -1) {
3159
                                session->media.audio_rtcp_fd = socket(AF_INET, SOCK_DGRAM, 0);
3160
                        }
3161
                        int rtp_port = g_random_int_range(10000, 60000);        /* FIXME Should this be configurable? */
3162
                        if(rtp_port % 2)
3163
                                rtp_port++;        /* Pick an even port for RTP */
3164
                        audio_rtp_address.sin_family = AF_INET;
3165
                        audio_rtp_address.sin_port = htons(rtp_port);
3166
                        inet_pton(AF_INET, local_ip, &audio_rtp_address.sin_addr.s_addr);
3167
                        if(bind(session->media.audio_rtp_fd, (struct sockaddr *)(&audio_rtp_address), sizeof(struct sockaddr)) < 0) {
3168
                                JANUS_LOG(LOG_ERR, "Bind failed for audio RTP (port %d), trying a different one...\n", rtp_port);
3169
                                attempts--;
3170
                                continue;
3171
                        }
3172
                        JANUS_LOG(LOG_VERB, "Audio RTP listener bound to port %d\n", rtp_port);
3173
                        int rtcp_port = rtp_port+1;
3174
                        audio_rtcp_address.sin_family = AF_INET;
3175
                        audio_rtcp_address.sin_port = htons(rtcp_port);
3176
                        inet_pton(AF_INET, local_ip, &audio_rtcp_address.sin_addr.s_addr);
3177
                        if(bind(session->media.audio_rtcp_fd, (struct sockaddr *)(&audio_rtcp_address), sizeof(struct sockaddr)) < 0) {
3178
                                JANUS_LOG(LOG_ERR, "Bind failed for audio RTCP (port %d), trying a different one...\n", rtcp_port);
3179
                                /* RTP socket is not valid anymore, reset it */
3180
                                close(session->media.audio_rtp_fd);
3181
                                session->media.audio_rtp_fd = -1;
3182
                                attempts--;
3183
                                continue;
3184
                        }
3185
                        JANUS_LOG(LOG_VERB, "Audio RTCP listener bound to port %d\n", rtcp_port);
3186
                        session->media.local_audio_rtp_port = rtp_port;
3187
                        session->media.local_audio_rtcp_port = rtcp_port;
3188
                }
3189
        }
3190
        if(session->media.has_video) {
3191
                JANUS_LOG(LOG_VERB, "Allocating video ports:\n");
3192
                struct sockaddr_in video_rtp_address, video_rtcp_address;
3193
                while(session->media.local_video_rtp_port == 0 || session->media.local_video_rtcp_port == 0) {
3194
                        if(attempts == 0)        /* Too many failures */
3195
                                return -1;
3196
                        if(session->media.video_rtp_fd == -1) {
3197
                                session->media.video_rtp_fd = socket(AF_INET, SOCK_DGRAM, 0);
3198
                        }
3199
                        if(session->media.video_rtcp_fd == -1) {
3200
                                session->media.video_rtcp_fd = socket(AF_INET, SOCK_DGRAM, 0);
3201
                        }
3202
                        int rtp_port = g_random_int_range(10000, 60000);        /* FIXME Should this be configurable? */
3203
                        if(rtp_port % 2)
3204
                                rtp_port++;        /* Pick an even port for RTP */
3205
                        video_rtp_address.sin_family = AF_INET;
3206
                        video_rtp_address.sin_port = htons(rtp_port);
3207
                        inet_pton(AF_INET, local_ip, &video_rtp_address.sin_addr.s_addr);
3208
                        if(bind(session->media.video_rtp_fd, (struct sockaddr *)(&video_rtp_address), sizeof(struct sockaddr)) < 0) {
3209
                                JANUS_LOG(LOG_ERR, "Bind failed for video RTP (port %d), trying a different one...\n", rtp_port);
3210
                                attempts--;
3211
                                continue;
3212
                        }
3213
                        JANUS_LOG(LOG_VERB, "Video RTP listener bound to port %d\n", rtp_port);
3214
                        int rtcp_port = rtp_port+1;
3215
                        video_rtcp_address.sin_family = AF_INET;
3216
                        video_rtcp_address.sin_port = htons(rtcp_port);
3217
                        inet_pton(AF_INET, local_ip, &video_rtcp_address.sin_addr.s_addr);
3218
                        if(bind(session->media.video_rtcp_fd, (struct sockaddr *)(&video_rtcp_address), sizeof(struct sockaddr)) < 0) {
3219
                                JANUS_LOG(LOG_ERR, "Bind failed for video RTCP (port %d), trying a different one...\n", rtcp_port);
3220
                                /* RTP socket is not valid anymore, reset it */
3221
                                close(session->media.video_rtp_fd);
3222
                                session->media.video_rtp_fd = -1;
3223
                                attempts--;
3224
                                continue;
3225
                        }
3226
                        JANUS_LOG(LOG_VERB, "Video RTCP listener bound to port %d\n", rtcp_port);
3227
                        session->media.local_video_rtp_port = rtp_port;
3228
                        session->media.local_video_rtcp_port = rtcp_port;
3229
                }
3230
        }
3231
        /* We need this to quickly interrupt the poll when it's time to update a session or wrap up */
3232
        pipe(session->media.pipefd);
3233
        return 0;
3234
}
3235

    
3236
/* Helper method to (re)connect RTP/RTCP sockets */
3237
static void janus_sip_connect_sockets(janus_sip_session *session, struct sockaddr_in *server_addr) {
3238
        if(!session || !server_addr)
3239
                return;
3240

    
3241
        if(session->media.updated) {
3242
                JANUS_LOG(LOG_VERB, "Updating session sockets\n");
3243
        }
3244

    
3245
        /* Connect peers (FIXME This pretty much sucks right now) */
3246
        if(session->media.remote_audio_rtp_port) {
3247
                server_addr->sin_port = htons(session->media.remote_audio_rtp_port);
3248
                if(connect(session->media.audio_rtp_fd, (struct sockaddr *)server_addr, sizeof(struct sockaddr)) == -1) {
3249
                        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);
3250
                        JANUS_LOG(LOG_ERR, "[SIP-%s]   -- %d (%s)\n", session->account.username, errno, strerror(errno));
3251
                }
3252
        }
3253
        if(session->media.remote_audio_rtcp_port) {
3254
                server_addr->sin_port = htons(session->media.remote_audio_rtcp_port);
3255
                if(connect(session->media.audio_rtcp_fd, (struct sockaddr *)server_addr, sizeof(struct sockaddr)) == -1) {
3256
                        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);
3257
                        JANUS_LOG(LOG_ERR, "[SIP-%s]   -- %d (%s)\n", session->account.username, errno, strerror(errno));
3258
                }
3259
        }
3260
        if(session->media.remote_video_rtp_port) {
3261
                server_addr->sin_port = htons(session->media.remote_video_rtp_port);
3262
                if(connect(session->media.video_rtp_fd, (struct sockaddr *)server_addr, sizeof(struct sockaddr)) == -1) {
3263
                        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);
3264
                        JANUS_LOG(LOG_ERR, "[SIP-%s]   -- %d (%s)\n", session->account.username, errno, strerror(errno));
3265
                }
3266
        }
3267
        if(session->media.remote_video_rtcp_port) {
3268
                server_addr->sin_port = htons(session->media.remote_video_rtcp_port);
3269
                if(connect(session->media.video_rtcp_fd, (struct sockaddr *)server_addr, sizeof(struct sockaddr)) == -1) {
3270
                        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);
3271
                        JANUS_LOG(LOG_ERR, "[SIP-%s]   -- %d (%s)\n", session->account.username, errno, strerror(errno));
3272
                }
3273
        }
3274

    
3275
}
3276

    
3277
/* Thread to relay RTP/RTCP frames coming from the SIP peer */
3278
static void *janus_sip_relay_thread(void *data) {
3279
        janus_sip_session *session = (janus_sip_session *)data;
3280
        if(!session || !session->account.username || !session->callee) {
3281
                g_thread_unref(g_thread_self());
3282
                return NULL;
3283
        }
3284
        JANUS_LOG(LOG_VERB, "Starting relay thread (%s <--> %s)\n", session->account.username, session->callee);
3285

    
3286
        gboolean have_server_ip = TRUE;
3287
        struct sockaddr_in server_addr;
3288
        memset(&server_addr, 0, sizeof(server_addr));
3289
        server_addr.sin_family = AF_INET;
3290
        if((inet_aton(session->media.remote_ip, &server_addr.sin_addr)) <= 0) {        /* Not a numeric IP... */
3291
                struct hostent *host = gethostbyname(session->media.remote_ip);        /* ...resolve name */
3292
                if(!host) {
3293
                        JANUS_LOG(LOG_ERR, "[SIP-%s] Couldn't get host (%s)\n", session->account.username, session->media.remote_ip);
3294
                        have_server_ip = FALSE;
3295
                } else {
3296
                        server_addr.sin_addr = *(struct in_addr *)host->h_addr_list;
3297
                }
3298
        }
3299
        if(have_server_ip)
3300
                janus_sip_connect_sockets(session, &server_addr);
3301

    
3302
        if(!session->callee) {
3303
                JANUS_LOG(LOG_VERB, "[SIP-%s] Leaving thread, no callee...\n", session->account.username);
3304
                g_thread_unref(g_thread_self());
3305
                return NULL;
3306
        }
3307
        /* File descriptors */
3308
        socklen_t addrlen;
3309
        struct sockaddr_in remote;
3310
        int resfd = 0, bytes = 0;
3311
        struct pollfd fds[5];
3312
        int pipe_fd = session->media.pipefd[0];
3313
        char buffer[1500];
3314
        memset(buffer, 0, 1500);
3315
        /* Loop */
3316
        int num = 0;
3317
        gboolean goon = TRUE;
3318
        int astep = 0, vstep = 0;
3319
        guint32 ats = 0, vts = 0;
3320
        while(goon && session != NULL && !session->destroyed &&
3321
                        session->status > janus_sip_call_status_idle &&
3322
                        session->status < janus_sip_call_status_closing) {        /* FIXME We need a per-call watchdog as well */
3323

    
3324
                if(session->media.updated) {
3325
                        /* Apparently there was a session update */
3326
                        if(have_server_ip && (inet_aton(session->media.remote_ip, &server_addr.sin_addr)) <= 0) {
3327
                                janus_sip_connect_sockets(session, &server_addr);
3328
                        } else {
3329
                                JANUS_LOG(LOG_ERR, "[SIP-%s] Couldn't update session details (missing or invalid remote IP address)\n", session->account.username);
3330
                        }
3331
                        session->media.updated = FALSE;
3332
                }
3333

    
3334
                /* Prepare poll */
3335
                num = 0;
3336
                if(session->media.audio_rtp_fd != -1) {
3337
                        fds[num].fd = session->media.audio_rtp_fd;
3338
                        fds[num].events = POLLIN;
3339
                        fds[num].revents = 0;
3340
                        num++;
3341
                }
3342
                if(session->media.audio_rtcp_fd != -1) {
3343
                        fds[num].fd = session->media.audio_rtcp_fd;
3344
                        fds[num].events = POLLIN;
3345
                        fds[num].revents = 0;
3346
                        num++;
3347
                }
3348
                if(session->media.video_rtp_fd != -1) {
3349
                        fds[num].fd = session->media.video_rtp_fd;
3350
                        fds[num].events = POLLIN;
3351
                        fds[num].revents = 0;
3352
                        num++;
3353
                }
3354
                if(session->media.video_rtcp_fd != -1) {
3355
                        fds[num].fd = session->media.video_rtcp_fd;
3356
                        fds[num].events = POLLIN;
3357
                        fds[num].revents = 0;
3358
                        num++;
3359
                }
3360
                if(pipe_fd != -1) {
3361
                        fds[num].fd = pipe_fd;
3362
                        fds[num].events = POLLIN;
3363
                        fds[num].revents = 0;
3364
                        num++;
3365
                }
3366
                /* Wait for some data */
3367
                resfd = poll(fds, num, 1000);
3368
                if(resfd < 0) {
3369
                        JANUS_LOG(LOG_ERR, "[SIP-%s] Error polling...\n", session->account.username);
3370
                        JANUS_LOG(LOG_ERR, "[SIP-%s]   -- %d (%s)\n", session->account.username, errno, strerror(errno));
3371
                        break;
3372
                } else if(resfd == 0) {
3373
                        /* No data, keep going */
3374
                        continue;
3375
                }
3376
                if(session == NULL || session->destroyed ||
3377
                                session->status <= janus_sip_call_status_idle ||
3378
                                session->status >= janus_sip_call_status_closing)
3379
                        break;
3380
                int i = 0;
3381
                for(i=0; i<num; i++) {
3382
                        if(fds[i].revents & (POLLERR | POLLHUP)) {
3383
                                /* Socket error? */
3384
                                JANUS_LOG(LOG_ERR, "[SIP-%s] Error polling: %s...\n", session->account.username,
3385
                                        fds[i].revents & POLLERR ? "POLLERR" : "POLLHUP");
3386
                                JANUS_LOG(LOG_ERR, "[SIP-%s]   -- %d (%s)\n", session->account.username, errno, strerror(errno));
3387
                                if(session->media.updated)
3388
                                        break;
3389
                                goon = FALSE;        /* Can we assume it's pretty much over, after a POLLERR? */
3390
                                /* FIXME Simulate a "hangup" coming from the browser */
3391
                                janus_sip_message *msg = g_malloc0(sizeof(janus_sip_message));
3392
                                msg->handle = session->handle;
3393
                                msg->message = json_pack("{ss}", "request", "hangup");
3394
                                msg->transaction = NULL;
3395
                                msg->jsep = NULL;
3396
                                g_async_queue_push(messages, msg);
3397
                                break;
3398
                        } else if(fds[i].revents & POLLIN) {
3399
                                if(pipe_fd != -1 && fds[i].fd == pipe_fd) {
3400
                                        /* Poll interrupted for a reason, go on */
3401
                                        int code = 0;
3402
                                        bytes = read(pipe_fd, &code, sizeof(int));
3403
                                        break;
3404
                                }
3405
                                /* Got an RTP/RTCP packet */
3406
                                if(session->media.audio_rtp_fd != -1 && fds[i].fd == session->media.audio_rtp_fd) {
3407
                                        /* Got something audio (RTP) */
3408
                                        addrlen = sizeof(remote);
3409
                                        bytes = recvfrom(session->media.audio_rtp_fd, buffer, 1500, 0, (struct sockaddr*)&remote, &addrlen);
3410
                                        rtp_header *header = (rtp_header *)buffer;
3411
                                        if(session->media.audio_ssrc_peer != ntohl(header->ssrc)) {
3412
                                                session->media.audio_ssrc_peer = ntohl(header->ssrc);
3413
                                                JANUS_LOG(LOG_VERB, "Got SIP peer audio SSRC: %"SCNu32"\n", session->media.audio_ssrc_peer);
3414
                                        }
3415
                                        /* Is this SRTP? */
3416
                                        if(session->media.has_srtp_remote) {
3417
                                                int buflen = bytes;
3418
                                                srtp_err_status_t res = srtp_unprotect(session->media.audio_srtp_in, buffer, &buflen);
3419
                                                if(res != srtp_err_status_ok && res != srtp_err_status_replay_fail && res != srtp_err_status_replay_old) {
3420
                                                        guint32 timestamp = ntohl(header->timestamp);
3421
                                                        guint16 seq = ntohs(header->seq_number);
3422
                                                        JANUS_LOG(LOG_ERR, "[SIP-%s] Audio SRTP unprotect error: %s (len=%d-->%d, ts=%"SCNu32", seq=%"SCNu16")\n",
3423
                                                                session->account.username, janus_sip_get_srtp_error(res), bytes, buflen, timestamp, seq);
3424
                                                        continue;
3425
                                                }
3426
                                                bytes = buflen;
3427
                                        }
3428
                                        /* Check if the SSRC changed (e.g., after a re-INVITE or UPDATE) */
3429
                                        guint32 ssrc = ntohl(header->ssrc);
3430
                                        guint32 timestamp = ntohl(header->timestamp);
3431
                                        guint16 seq = ntohs(header->seq_number);
3432
                                        if(ssrc != session->media.context.a_last_ssrc) {
3433
                                                JANUS_LOG(LOG_VERB, "Audio SSRC changed (re-INVITE?), %"SCNu32" --> %"SCNu32"\n",
3434
                                                        session->media.context.a_last_ssrc, ssrc);
3435
                                                session->media.context.a_last_ssrc = ssrc;
3436
                                                session->media.context.a_base_ts_prev = session->media.context.a_last_ts;
3437
                                                session->media.context.a_base_ts = timestamp;
3438
                                                session->media.context.a_base_seq_prev = session->media.context.a_last_seq;
3439
                                                session->media.context.a_base_seq = seq;
3440
                                        }
3441
                                        /* Compute a coherent timestamp and sequence number */
3442
                                        session->media.context.a_last_ts = (timestamp-session->media.context.a_base_ts)
3443
                                                + session->media.context.a_base_ts_prev+(astep ? astep : 960);        /* FIXME */
3444
                                        session->media.context.a_last_seq = (seq-session->media.context.a_base_seq)+session->media.context.a_base_seq_prev+1;
3445
                                        /* Update the timestamp and sequence number in the RTP packet, and send it */
3446
                                        header->timestamp = htonl(session->media.context.a_last_ts);
3447
                                        header->seq_number = htons(session->media.context.a_last_seq);
3448
                                        if(ats == 0) {
3449
                                                ats = timestamp;
3450
                                        } else if(astep == 0) {
3451
                                                astep = timestamp-ats;
3452
                                                if(astep < 0)
3453
                                                        astep = 0;
3454
                                        }
3455
                                        /* Save the frame if we're recording */
3456
                                        janus_recorder_save_frame(session->arc_peer, buffer, bytes);
3457
                                        /* Relay to browser */
3458
                                        gateway->relay_rtp(session->handle, 0, buffer, bytes);
3459
                                        continue;
3460
                                } else if(session->media.audio_rtcp_fd != -1 && fds[i].fd == session->media.audio_rtcp_fd) {
3461
                                        /* Got something audio (RTCP) */
3462
                                        addrlen = sizeof(remote);
3463
                                        bytes = recvfrom(session->media.audio_rtcp_fd, buffer, 1500, 0, (struct sockaddr*)&remote, &addrlen);
3464
                                        //~ JANUS_LOG(LOG_VERB, "************************\nGot %d bytes on the audio RTCP channel...\n", bytes);
3465
                                        /* Is this SRTCP? */
3466
                                        if(session->media.has_srtp_remote) {
3467
                                                int buflen = bytes;
3468
                                                srtp_err_status_t res = srtp_unprotect_rtcp(session->media.audio_srtp_in, buffer, &buflen);
3469
                                                if(res != srtp_err_status_ok && res != srtp_err_status_replay_fail && res != srtp_err_status_replay_old) {
3470
                                                        JANUS_LOG(LOG_ERR, "[SIP-%s] Audio SRTCP unprotect error: %s (len=%d-->%d)\n",
3471
                                                                session->account.username, janus_sip_get_srtp_error(res), bytes, buflen);
3472
                                                        continue;
3473
                                                }
3474
                                                bytes = buflen;
3475
                                        }
3476
                                        /* Relay to browser */
3477
                                        gateway->relay_rtcp(session->handle, 0, buffer, bytes);
3478
                                        continue;
3479
                                } else if(session->media.video_rtp_fd != -1 && fds[i].fd == session->media.video_rtp_fd) {
3480
                                        /* Got something video (RTP) */
3481
                                        addrlen = sizeof(remote);
3482
                                        bytes = recvfrom(session->media.video_rtp_fd, buffer, 1500, 0, (struct sockaddr*)&remote, &addrlen);
3483
                                        //~ JANUS_LOG(LOG_VERB, "************************\nGot %d bytes on the video RTP channel...\n", bytes);
3484
                                        //~ rtp_header_t *rtp = (rtp_header_t *)buffer;
3485
                                        //~ JANUS_LOG(LOG_VERB, " ... parsed RTP packet (ssrc=%u, pt=%u, seq=%u, ts=%u)...\n",
3486
                                                //~ ntohl(rtp->ssrc), rtp->type, ntohs(rtp->seq_number), ntohl(rtp->timestamp));
3487
                                        rtp_header *header = (rtp_header *)buffer;
3488
                                        if(session->media.video_ssrc_peer != ntohl(header->ssrc)) {
3489
                                                session->media.video_ssrc_peer = ntohl(header->ssrc);
3490
                                                JANUS_LOG(LOG_VERB, "Got SIP peer video SSRC: %"SCNu32"\n", session->media.video_ssrc_peer);
3491
                                        }
3492
                                        /* Is this SRTP? */
3493
                                        if(session->media.has_srtp_remote) {
3494
                                                int buflen = bytes;
3495
                                                srtp_err_status_t res = srtp_unprotect(session->media.video_srtp_in, buffer, &buflen);
3496
                                                if(res != srtp_err_status_ok && res != srtp_err_status_replay_fail && res != srtp_err_status_replay_old) {
3497
                                                        guint32 timestamp = ntohl(header->timestamp);
3498
                                                        guint16 seq = ntohs(header->seq_number);
3499
                                                        JANUS_LOG(LOG_ERR, "[SIP-%s] Video SRTP unprotect error: %s (len=%d-->%d, ts=%"SCNu32", seq=%"SCNu16")\n",
3500
                                                                session->account.username, janus_sip_get_srtp_error(res), bytes, buflen, timestamp, seq);
3501
                                                        continue;
3502
                                                }
3503
                                                bytes = buflen;
3504
                                        }
3505
                                        /* Check if the SSRC changed (e.g., after a re-INVITE or UPDATE) */
3506
                                        guint32 ssrc = ntohl(header->ssrc);
3507
                                        guint32 timestamp = ntohl(header->timestamp);
3508
                                        guint16 seq = ntohs(header->seq_number);
3509
                                        if(ssrc != session->media.context.v_last_ssrc) {
3510
                                                JANUS_LOG(LOG_VERB, "Video SSRC changed (re-INVITE?)\n");
3511
                                                session->media.context.v_last_ssrc = ssrc;
3512
                                                session->media.context.v_base_ts_prev = session->media.context.v_last_ts;
3513
                                                session->media.context.v_base_ts = timestamp;
3514
                                                session->media.context.v_base_seq_prev = session->media.context.v_last_seq;
3515
                                                session->media.context.v_base_seq = seq;
3516
                                        }
3517
                                        /* Compute a coherent timestamp and sequence number */
3518
                                        session->media.context.v_last_ts = (timestamp-session->media.context.v_base_ts)
3519
                                                + session->media.context.v_base_ts_prev+(vstep ? vstep : 4500);        /* FIXME */
3520
                                        session->media.context.v_last_seq = (seq-session->media.context.v_base_seq)+session->media.context.v_base_seq_prev+1;
3521
                                        /* Update the timestamp and sequence number in the RTP packet, and send it */
3522
                                        header->timestamp = htonl(session->media.context.v_last_ts);
3523
                                        header->seq_number = htons(session->media.context.v_last_seq);
3524
                                        if(vts == 0) {
3525
                                                vts = timestamp;
3526
                                        } else if(vstep == 0) {
3527
                                                vstep = timestamp-vts;
3528
                                                if(vstep < 0)
3529
                                                        vstep = 0;
3530
                                        }
3531
                                        /* Save the frame if we're recording */
3532
                                        janus_recorder_save_frame(session->vrc_peer, buffer, bytes);
3533
                                        /* Relay to browser */
3534
                                        gateway->relay_rtp(session->handle, 1, buffer, bytes);
3535
                                        continue;
3536
                                } else if(session->media.video_rtcp_fd != -1 && fds[i].fd == session->media.video_rtcp_fd) {
3537
                                        /* Got something video (RTCP) */
3538
                                        addrlen = sizeof(remote);
3539
                                        bytes = recvfrom(session->media.video_rtcp_fd, buffer, 1500, 0, (struct sockaddr*)&remote, &addrlen);
3540
                                        //~ JANUS_LOG(LOG_VERB, "************************\nGot %d bytes on the video RTCP channel...\n", bytes);
3541
                                        /* Is this SRTCP? */
3542
                                        if(session->media.has_srtp_remote) {
3543
                                                int buflen = bytes;
3544
                                                srtp_err_status_t res = srtp_unprotect_rtcp(session->media.video_srtp_in, buffer, &buflen);
3545
                                                if(res != srtp_err_status_ok && res != srtp_err_status_replay_fail && res != srtp_err_status_replay_old) {
3546
                                                        JANUS_LOG(LOG_ERR, "[SIP-%s] Video SRTP unprotect error: %s (len=%d-->%d)\n",
3547
                                                                session->account.username, janus_sip_get_srtp_error(res), bytes, buflen);
3548
                                                        continue;
3549
                                                }
3550
                                                bytes = buflen;
3551
                                        }
3552
                                        /* Relay to browser */
3553
                                        gateway->relay_rtcp(session->handle, 1, buffer, bytes);
3554
                                        continue;
3555
                                }
3556
                        }
3557
                }
3558
        }
3559
        if(session->media.audio_rtp_fd != -1) {
3560
                close(session->media.audio_rtp_fd);
3561
                session->media.audio_rtp_fd = -1;
3562
        }
3563
        if(session->media.audio_rtcp_fd != -1) {
3564
                close(session->media.audio_rtcp_fd);
3565
                session->media.audio_rtcp_fd = -1;
3566
        }
3567
        session->media.local_audio_rtp_port = 0;
3568
        session->media.local_audio_rtcp_port = 0;
3569
        session->media.audio_ssrc = 0;
3570
        if(session->media.video_rtp_fd != -1) {
3571
                close(session->media.video_rtp_fd);
3572
                session->media.video_rtp_fd = -1;
3573
        }
3574
        if(session->media.video_rtcp_fd != -1) {
3575
                close(session->media.video_rtcp_fd);
3576
                session->media.video_rtcp_fd = -1;
3577
        }
3578
        session->media.local_video_rtp_port = 0;
3579
        session->media.local_video_rtcp_port = 0;
3580
        session->media.video_ssrc = 0;
3581
        if(session->media.pipefd[0] > 0) {
3582
                close(session->media.pipefd[0]);
3583
                session->media.pipefd[0] = -1;
3584
        }
3585
        if(session->media.pipefd[1] > 0) {
3586
                close(session->media.pipefd[1]);
3587
                session->media.pipefd[1] = -1;
3588
        }
3589
        /* Clean up SRTP stuff, if needed */
3590
        janus_sip_srtp_cleanup(session);
3591
        /* Done */
3592
        JANUS_LOG(LOG_VERB, "Leaving SIP relay thread\n");
3593
        g_thread_unref(g_thread_self());
3594
        return NULL;
3595
}
3596

    
3597

    
3598
/* Sofia Event thread */
3599
gpointer janus_sip_sofia_thread(gpointer user_data) {
3600
        janus_sip_session *session = (janus_sip_session *)user_data;
3601
        if(session == NULL || session->account.username == NULL) {
3602
                g_thread_unref(g_thread_self());
3603
                return NULL;
3604
        }
3605
        JANUS_LOG(LOG_VERB, "Joining sofia loop thread (%s)...\n", session->account.username);
3606
        session->stack = g_malloc0(sizeof(ssip_t));
3607
        session->stack->session = session;
3608
        session->stack->s_nua = NULL;
3609
        session->stack->s_nh_r = NULL;
3610
        session->stack->s_nh_i = NULL;
3611
        session->stack->s_root = su_root_create(session->stack);
3612
        su_home_init(session->stack->s_home);
3613
        JANUS_LOG(LOG_VERB, "Setting up sofia stack (sip:%s@%s)\n", session->account.username, local_ip);
3614
        char sip_url[128];
3615
        char sips_url[128];
3616
        char *ipv6;
3617
        ipv6 = strstr(local_ip, ":");
3618
        g_snprintf(sip_url, sizeof(sip_url), "sip:%s%s%s:*", ipv6 ? "[" : "", local_ip, ipv6 ? "]" : "");
3619
        g_snprintf(sips_url, sizeof(sips_url), "sips:%s%s%s:*", ipv6 ? "[" : "", local_ip, ipv6 ? "]" : "");
3620
        char outbound_options[256] = "use-rport no-validate";
3621
        if(keepalive_interval > 0)
3622
                g_strlcat(outbound_options, " options-keepalive", sizeof(outbound_options));
3623
        if(!behind_nat)
3624
                g_strlcat(outbound_options, " no-natify", sizeof(outbound_options));
3625
        session->stack->s_nua = nua_create(session->stack->s_root,
3626
                                janus_sip_sofia_callback,
3627
                                session,
3628
                                SIPTAG_ALLOW_STR("INVITE, ACK, BYE, CANCEL, OPTIONS, UPDATE"),
3629
                                NUTAG_M_USERNAME(session->account.username),
3630
                                NUTAG_URL(sip_url),
3631
                                TAG_IF(session->account.sips, NUTAG_SIPS_URL(sips_url)),
3632
                                SIPTAG_USER_AGENT_STR(session->account.user_agent ? session->account.user_agent : user_agent),
3633
                                NUTAG_KEEPALIVE(keepalive_interval * 1000),        /* Sofia expects it in milliseconds */
3634
                                NUTAG_OUTBOUND(outbound_options),
3635
                                SIPTAG_SUPPORTED(NULL),
3636
                                TAG_NULL());
3637
        su_root_run(session->stack->s_root);
3638
        /* When we get here, we're done */
3639
        nua_destroy(session->stack->s_nua);
3640
        su_root_destroy(session->stack->s_root);
3641
        session->stack->s_root = NULL;
3642
        su_home_deinit(session->stack->s_home);
3643
        su_home_unref(session->stack->s_home);
3644
        if (session->stack) {
3645
                g_free(session->stack);
3646
                session->stack = NULL;
3647
        }
3648
        //~ stop = 1;
3649
        JANUS_LOG(LOG_VERB, "Leaving sofia loop thread...\n");
3650
        g_thread_unref(g_thread_self());
3651
        /* Cleaning up and removing the session is done in a lazy way */
3652
        janus_mutex_lock(&sessions_mutex);
3653
        old_sessions = g_list_append(old_sessions, session);
3654
        janus_mutex_unlock(&sessions_mutex);
3655
        return NULL;
3656
}