Statistics
| Branch: | Revision:

janus-gateway / plugins / janus_sip.c @ 9962c767

History | View | Annotate | Download (124 KB)

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

    
51
#include "plugin.h"
52

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

    
56
#include <jansson.h>
57

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

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

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

    
78

    
79
/* Plugin information */
80
#define JANUS_SIP_VERSION                        6
81
#define JANUS_SIP_VERSION_STRING        "0.0.6"
82
#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."
83
#define JANUS_SIP_NAME                                "JANUS SIP plugin"
84
#define JANUS_SIP_AUTHOR                        "Meetecho s.r.l."
85
#define JANUS_SIP_PACKAGE                        "janus.plugin.sip"
86

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

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

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

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

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

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

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

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

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

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

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

    
203
        msg->handle = NULL;
204

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

    
214
        g_free(msg);
215
}
216

    
217

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

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

    
246

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

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

    
272

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

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

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

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

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

    
345

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

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

    
361

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

    
502

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

    
514

    
515
/* URI parsing utilies */
516

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

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

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

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

    
555

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

    
637

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

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

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

    
668

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

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

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

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

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

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

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

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

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

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

    
766
        g_atomic_int_set(&initialized, 1);
767

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

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

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

    
811
        /* Deinitialize sofia */
812
        su_deinit();
813

    
814
        JANUS_LOG(LOG_INFO, "%s destroyed!\n", JANUS_SIP_NAME);
815
}
816

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

    
822
int janus_sip_get_version(void) {
823
        return JANUS_SIP_VERSION;
824
}
825

    
826
const char *janus_sip_get_version_string(void) {
827
        return JANUS_SIP_VERSION_STRING;
828
}
829

    
830
const char *janus_sip_get_description(void) {
831
        return JANUS_SIP_DESCRIPTION;
832
}
833

    
834
const char *janus_sip_get_name(void) {
835
        return JANUS_SIP_NAME;
836
}
837

    
838
const char *janus_sip_get_author(void) {
839
        return JANUS_SIP_AUTHOR;
840
}
841

    
842
const char *janus_sip_get_package(void) {
843
        return JANUS_SIP_PACKAGE;
844
}
845

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

    
906
        janus_mutex_lock(&sessions_mutex);
907
        g_hash_table_insert(sessions, handle, session);
908
        janus_mutex_unlock(&sessions_mutex);
909

    
910
        return;
911
}
912

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

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

    
982
struct janus_plugin_result *janus_sip_handle_message(janus_plugin_session *handle, char *transaction, json_t *message, json_t *jsep) {
983
        if(g_atomic_int_get(&stopping) || !g_atomic_int_get(&initialized))
984
                return janus_plugin_result_new(JANUS_PLUGIN_ERROR, g_atomic_int_get(&stopping) ? "Shutting down" : "Plugin not initialized", NULL);
985
        janus_sip_message *msg = g_malloc0(sizeof(janus_sip_message));
986
        msg->handle = handle;
987
        msg->transaction = transaction;
988
        msg->message = message;
989
        msg->jsep = jsep;
990
        g_async_queue_push(messages, msg);
991

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

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

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

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

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

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

    
1269
                if(!strcasecmp(request_text, "register")) {
1270
                        /* Send a REGISTER */
1271
                        if(session->account.registration_status > janus_sip_registration_status_unregistered) {
1272
                                JANUS_LOG(LOG_ERR, "Already registered (%s)\n", session->account.username);
1273
                                error_code = JANUS_SIP_ERROR_ALREADY_REGISTERED;
1274
                                g_snprintf(error_cause, 512, "Already registered (%s)", session->account.username);
1275
                                goto error;
1276
                        }
1277

    
1278
                        /* Cleanup old values */
1279
                        if(session->account.identity != NULL)
1280
                                g_free(session->account.identity);
1281
                        session->account.identity = NULL;
1282
                        session->account.sips = TRUE;
1283
                        if(session->account.username != NULL)
1284
                                g_free(session->account.username);
1285
                        session->account.username = NULL;
1286
                        if(session->account.display_name != NULL)
1287
                                g_free(session->account.display_name);
1288
                        session->account.display_name = NULL;
1289
                        if(session->account.authuser != NULL)
1290
                                g_free(session->account.authuser);
1291
                        session->account.authuser = NULL;
1292
                        if(session->account.secret != NULL)
1293
                                g_free(session->account.secret);
1294
                        session->account.secret = NULL;
1295
                        session->account.secret_type = janus_sip_secret_type_unknown;
1296
                        if(session->account.proxy != NULL)
1297
                                g_free(session->account.proxy);
1298
                        session->account.proxy = NULL;
1299
                        if(session->account.user_agent != NULL)
1300
                                g_free(session->account.user_agent);
1301
                        session->account.user_agent = NULL;
1302
                        session->account.registration_status = janus_sip_registration_status_unregistered;
1303

    
1304
                        gboolean guest = FALSE;
1305
                        JANUS_VALIDATE_JSON_OBJECT(root, register_parameters,
1306
                                error_code, error_cause, TRUE,
1307
                                JANUS_SIP_ERROR_MISSING_ELEMENT, JANUS_SIP_ERROR_INVALID_ELEMENT);
1308
                        if(error_code != 0)
1309
                                goto error;
1310
                        json_t *type = json_object_get(root, "type");
1311
                        if(type != NULL) {
1312
                                const char *type_text = json_string_value(type);
1313
                                if(!strcmp(type_text, "guest")) {
1314
                                        JANUS_LOG(LOG_INFO, "Registering as a guest\n");
1315
                                        guest = TRUE;
1316
                                } else {
1317
                                        JANUS_LOG(LOG_WARN, "Unknown type '%s', ignoring...\n", type_text);
1318
                                }
1319
                        }
1320

    
1321
                        gboolean send_register = TRUE;
1322
                        json_t *do_register = json_object_get(root, "send_register");
1323
                        if(do_register != NULL) {
1324
                                if(guest) {
1325
                                        JANUS_LOG(LOG_ERR, "Conflicting elements: send_register cannot be true if guest is true\n");
1326
                                        error_code = JANUS_SIP_ERROR_INVALID_ELEMENT;
1327
                                        g_snprintf(error_cause, 512, "Conflicting elements: send_register cannot be true if guest is true");
1328
                                        goto error;
1329
                                }
1330
                                send_register = json_is_true(do_register);
1331
                        }
1332

    
1333
                        gboolean sips = TRUE;
1334
                        json_t *do_sips = json_object_get(root, "sips");
1335
                        if(do_sips != NULL) {
1336
                                sips = json_is_true(do_sips);
1337
                        }
1338

    
1339
                        /* Parse address */
1340
                        json_t *proxy = json_object_get(root, "proxy");
1341
                        const char *proxy_text = NULL;
1342

    
1343
                        if (proxy && !json_is_null(proxy)) {
1344
                                /* Has to be validated separately because it could be null */
1345
                                JANUS_VALIDATE_JSON_OBJECT(root, proxy_parameters,
1346
                                        error_code, error_cause, TRUE,
1347
                                        JANUS_SIP_ERROR_MISSING_ELEMENT, JANUS_SIP_ERROR_INVALID_ELEMENT);
1348
                                if(error_code != 0)
1349
                                        goto error;
1350
                                proxy_text = json_string_value(proxy);
1351
                                janus_sip_uri_t proxy_uri;
1352
                                if (janus_sip_parse_proxy_uri(&proxy_uri, proxy_text) < 0) {
1353
                                        JANUS_LOG(LOG_ERR, "Invalid proxy address %s\n", proxy_text);
1354
                                        error_code = JANUS_SIP_ERROR_INVALID_ADDRESS;
1355
                                        g_snprintf(error_cause, 512, "Invalid proxy address %s\n", proxy_text);
1356
                                        goto error;
1357
                                }
1358
                        }
1359

    
1360
                        /* Parse register TTL */
1361
                        int ttl = register_ttl;
1362
                        json_t *reg_ttl = json_object_get(root, "register_ttl");
1363
                        if (reg_ttl && json_is_integer(reg_ttl))
1364
                                ttl = json_integer_value(reg_ttl);
1365
                        if (ttl <= 0)
1366
                                ttl = JANUS_DEFAULT_REGISTER_TTL;
1367

    
1368
                        /* Parse display name */
1369
                        const char* display_name_text = NULL;
1370
                        json_t *display_name = json_object_get(root, "display_name");
1371
                        if (display_name && json_is_string(display_name))
1372
                                display_name_text = json_string_value(display_name);
1373

    
1374
                        /* Parse user agent */
1375
                        const char* user_agent_text = NULL;
1376
                        json_t *user_agent = json_object_get(root, "user_agent");
1377
                        if (user_agent && json_is_string(user_agent))
1378
                                user_agent_text = json_string_value(user_agent);
1379

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

    
1447
                        session->account.identity = g_strdup(username_text);
1448
                        session->account.sips = sips;
1449
                        session->account.username = g_strdup(user_id);
1450
                        if (display_name_text) {
1451
                                session->account.display_name = g_strdup(display_name_text);
1452
                        }
1453
                        if (user_agent_text) {
1454
                                session->account.user_agent = g_strdup(user_agent_text);
1455
                        }
1456
                        if (proxy_text) {
1457
                                session->account.proxy = g_strdup(proxy_text);
1458
                        }
1459

    
1460
                        session->account.registration_status = janus_sip_registration_status_registering;
1461
                        if(session->stack == NULL) {
1462
                                /* Start the thread first */
1463
                                GError *error = NULL;
1464
                                char tname[16];
1465
                                g_snprintf(tname, sizeof(tname), "sip %s", session->account.username);
1466
                                g_thread_try_new(tname, janus_sip_sofia_thread, session, &error);
1467
                                if(error != NULL) {
1468
                                        JANUS_LOG(LOG_ERR, "Got error %d (%s) trying to launch the SIP Sofia thread...\n", error->code, error->message ? error->message : "??");
1469
                                        error_code = JANUS_SIP_ERROR_UNKNOWN_ERROR;
1470
                                        g_snprintf(error_cause, 512, "Got error %d (%s) trying to launch the SIP Sofia thread", error->code, error->message ? error->message : "??");
1471
                                        goto error;
1472
                                }
1473
                                long int timeout = 0;
1474
                                while(session->stack == NULL || session->stack->s_nua == NULL) {
1475
                                        g_usleep(100000);
1476
                                        timeout += 100000;
1477
                                        if(timeout >= 2000000) {
1478
                                                break;
1479
                                        }
1480
                                }
1481
                                if(timeout >= 2000000) {
1482
                                        JANUS_LOG(LOG_ERR, "Two seconds passed and still no NUA, problems with the thread?\n");
1483
                                        error_code = JANUS_SIP_ERROR_UNKNOWN_ERROR;
1484
                                        g_snprintf(error_cause, 512, "Two seconds passed and still no NUA, problems with the thread?");
1485
                                        goto error;
1486
                                }
1487
                        }
1488
                        if(session->stack->s_nh_r != NULL) {
1489
                                nua_handle_destroy(session->stack->s_nh_r);
1490
                                session->stack->s_nh_r = NULL;
1491
                        }
1492

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

    
2122
                        char payload[64];
2123
                        g_snprintf(payload, sizeof(payload), "Signal=%s\r\nDuration=%d", digit_text, duration_ms);
2124
                        nua_info(session->stack->s_nh_i,
2125
                                SIPTAG_CONTENT_TYPE_STR("application/dtmf-relay"),
2126
                                SIPTAG_PAYLOAD_STR(payload),
2127
                                TAG_END());
2128
                } else {
2129
                        JANUS_LOG(LOG_ERR, "Unknown request (%s)\n", request_text);
2130
                        error_code = JANUS_SIP_ERROR_INVALID_REQUEST;
2131
                        g_snprintf(error_cause, 512, "Unknown request (%s)", request_text);
2132
                        goto error;
2133
                }
2134

    
2135
                /* Prepare JSON event */
2136
                json_t *event = json_object();
2137
                json_object_set_new(event, "sip", json_string("event"));
2138
                if(result != NULL)
2139
                        json_object_set_new(event, "result", result);
2140
                int ret = gateway->push_event(msg->handle, &janus_sip_plugin, msg->transaction, event, NULL);
2141
                JANUS_LOG(LOG_VERB, "  >> Pushing event: %d (%s)\n", ret, janus_get_api_error(ret));
2142
                json_decref(event);
2143
                janus_sip_message_free(msg);
2144
                continue;
2145

    
2146
error:
2147
                {
2148
                        /* Prepare JSON error event */
2149
                        json_t *event = json_object();
2150
                        json_object_set_new(event, "sip", json_string("event"));
2151
                        json_object_set_new(event, "error_code", json_integer(error_code));
2152
                        json_object_set_new(event, "error", json_string(error_cause));
2153
                        int ret = gateway->push_event(msg->handle, &janus_sip_plugin, msg->transaction, event, NULL);
2154
                        JANUS_LOG(LOG_VERB, "  >> Pushing event: %d (%s)\n", ret, janus_get_api_error(ret));
2155
                        json_decref(event);
2156
                        janus_sip_message_free(msg);
2157
                }
2158
        }
2159
        JANUS_LOG(LOG_VERB, "Leaving SIP handler thread\n");
2160
        return NULL;
2161
}
2162

    
2163

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

    
2375
                        if(status < 200) {
2376
                                /* Not ready yet (FIXME May this be pranswer?? we don't handle it yet...) */
2377
                                break;
2378
                        } else if(status == 401 || status == 407) {
2379
                                char auth[256];
2380
                                const char* scheme;
2381
                                const char* realm;
2382
                                if(status == 401) {
2383
                                         /* Get scheme/realm from 401 error */
2384
                                        sip_www_authenticate_t const* www_auth = sip->sip_www_authenticate;
2385
                                        scheme = www_auth->au_scheme;
2386
                                        realm = msg_params_find(www_auth->au_params, "realm=");
2387
                                } else {
2388
                                         /* Get scheme/realm from 407 error, proxy-auth */
2389
                                        sip_proxy_authenticate_t const* proxy_auth = sip->sip_proxy_authenticate;
2390
                                        scheme = proxy_auth->au_scheme;
2391
                                        realm = msg_params_find(proxy_auth->au_params, "realm=");
2392
                                }
2393
                                memset(auth, 0, sizeof(auth));
2394
                                g_snprintf(auth, sizeof(auth), "%s%s:%s:%s:%s%s",
2395
                                        session->account.secret_type == janus_sip_secret_type_hashed ? "HA1+" : "",
2396
                                        scheme,
2397
                                        realm,
2398
                                        session->account.authuser ? session->account.authuser : "null",
2399
                                        session->account.secret_type == janus_sip_secret_type_hashed ? "HA1+" : "",
2400
                                        session->account.secret ? session->account.secret : "null");
2401
                                JANUS_LOG(LOG_VERB, "\t%s\n", auth);
2402
                                /* Authenticate */
2403
                                nua_authenticate(nh,
2404
                                        NUTAG_AUTH(auth),
2405
                                        TAG_END());
2406
                                break;
2407
                        } else if(status >= 400) {
2408
                                break;
2409
                        }
2410
                        if(ssip == NULL) {
2411
                                JANUS_LOG(LOG_ERR, "\tInvalid SIP stack\n");
2412
                                nua_respond(nh, 500, sip_status_phrase(500), TAG_END());
2413
                                break;
2414
                        }
2415
                        char sdperror[100];
2416
                        janus_sdp *sdp = janus_sdp_parse(sip->sip_payload->pl_data, sdperror, sizeof(sdperror));
2417
                        if(!sdp) {
2418
                                JANUS_LOG(LOG_ERR, "\tError parsing SDP! %s\n", sdperror);
2419
                                nua_respond(nh, 488, sip_status_phrase(488), TAG_END());
2420
                                break;
2421
                        }
2422
                        /* Send an ACK, if needed */
2423
                        if(!session->media.autoack) {
2424
                                char *route = sip->sip_record_route ? url_as_string(session->stack->s_home, sip->sip_record_route->r_url) : NULL;
2425
                                JANUS_LOG(LOG_INFO, "Sending ACK (route=%s)\n", route ? route : "none");
2426
                                nua_ack(nh,
2427
                                        TAG_IF(route, NTATAG_DEFAULT_PROXY(route)),
2428
                                        TAG_END());
2429
                        }
2430
                        /* Parse SDP */
2431
                        JANUS_LOG(LOG_VERB, "Peer accepted our call:\n%s", sip->sip_payload->pl_data);
2432
                        session->status = janus_sip_call_status_incall;
2433
                        char *fixed_sdp = g_strdup(sip->sip_payload->pl_data);
2434
                        janus_sip_sdp_process(session, sdp, TRUE);
2435
                        /* If we asked for SRTP and are not getting it, fail */
2436
                        if(session->media.require_srtp && !session->media.has_srtp_remote) {
2437
                                JANUS_LOG(LOG_ERR, "\tWe asked for mandatory SRTP but didn't get any in the reply!\n");
2438
                                janus_sdp_free(sdp);
2439
                                g_free(fixed_sdp);
2440
                                /* Hangup immediately */
2441
                                session->status = janus_sip_call_status_closing;
2442
                                nua_bye(nh, TAG_END());
2443
                                g_free(session->callee);
2444
                                session->callee = NULL;
2445
                                break;
2446
                        }
2447
                        if(session->media.audio_pt > -1) {
2448
                                session->media.audio_pt_name = janus_get_codec_from_pt(fixed_sdp, session->media.audio_pt);
2449
                                JANUS_LOG(LOG_VERB, "Detected audio codec: %d (%s)\n", session->media.audio_pt, session->media.audio_pt_name);
2450
                        }
2451
                        if(session->media.video_pt > -1) {
2452
                                session->media.video_pt_name = janus_get_codec_from_pt(fixed_sdp, session->media.video_pt);
2453
                                JANUS_LOG(LOG_VERB, "Detected video codec: %d (%s)\n", session->media.video_pt, session->media.video_pt_name);
2454
                        }
2455
                        session->media.ready = 1;        /* FIXME Maybe we need a better way to signal this */
2456
                        GError *error = NULL;
2457
                        char tname[16];
2458
                        g_snprintf(tname, sizeof(tname), "siprtp %s", session->account.username);
2459
                        g_thread_try_new(tname, janus_sip_relay_thread, session, &error);
2460
                        if(error != NULL) {
2461
                                JANUS_LOG(LOG_ERR, "Got error %d (%s) trying to launch the RTP/RTCP thread...\n", error->code, error->message ? error->message : "??");
2462
                        }
2463
                        /* Send SDP to the browser */
2464
                        json_t *jsep = json_pack("{ssss}", "type", "answer", "sdp", fixed_sdp);
2465
                        json_t *call = json_object();
2466
                        json_object_set_new(call, "sip", json_string("event"));
2467
                        json_t *calling = json_object();
2468
                        json_object_set_new(calling, "event", json_string("accepted"));
2469
                        json_object_set_new(calling, "username", json_string(session->callee));
2470
                        json_object_set_new(call, "result", calling);
2471
                        int ret = gateway->push_event(session->handle, &janus_sip_plugin, session->transaction, call, jsep);
2472
                        JANUS_LOG(LOG_VERB, "  >> Pushing event to peer: %d (%s)\n", ret, janus_get_api_error(ret));
2473
                        json_decref(call);
2474
                        json_decref(jsep);
2475
                        g_free(fixed_sdp);
2476
                        janus_sdp_free(sdp);
2477
                        break;
2478
                }
2479
                case nua_r_register: {
2480
                        JANUS_LOG(LOG_VERB, "[%s][%s]: %d %s\n", session->account.username, nua_event_name(event), status, phrase ? phrase : "??");
2481
                        if(status == 200) {
2482
                                if(session->account.registration_status < janus_sip_registration_status_registered)
2483
                                        session->account.registration_status = janus_sip_registration_status_registered;
2484
                                JANUS_LOG(LOG_VERB, "Successfully registered\n");
2485
                                /* Notify the browser */
2486
                                json_t *call = json_object();
2487
                                json_object_set_new(call, "sip", json_string("event"));
2488
                                json_t *calling = json_object();
2489
                                json_object_set_new(calling, "event", json_string("registered"));
2490
                                json_object_set_new(calling, "username", json_string(session->account.username));
2491
                                json_object_set_new(calling, "register_sent", json_true());
2492
                                json_object_set_new(call, "result", calling);
2493
                                int ret = gateway->push_event(session->handle, &janus_sip_plugin, session->transaction, call, NULL);
2494
                                JANUS_LOG(LOG_VERB, "  >> Pushing event to peer: %d (%s)\n", ret, janus_get_api_error(ret));
2495
                                json_decref(call);
2496
                        } else if(status == 401) {
2497
                                /* Get scheme/realm from 401 error */
2498
                                sip_www_authenticate_t const* www_auth = sip->sip_www_authenticate;
2499
                                char const* scheme = www_auth->au_scheme;
2500
                                const char* realm = msg_params_find(www_auth->au_params, "realm=");
2501
                                char auth[256];
2502
                                memset(auth, 0, sizeof(auth));
2503
                                g_snprintf(auth, sizeof(auth), "%s%s:%s:%s:%s%s",
2504
                                        session->account.secret_type == janus_sip_secret_type_hashed ? "HA1+" : "",
2505
                                        scheme,
2506
                                        realm,
2507
                                        session->account.authuser ? session->account.authuser : "null",
2508
                                        session->account.secret_type == janus_sip_secret_type_hashed ? "HA1+" : "",
2509
                                        session->account.secret);
2510
                                JANUS_LOG(LOG_VERB, "\t%s\n", auth);
2511
                                /* Authenticate */
2512
                                nua_authenticate(nh,
2513
                                        NUTAG_AUTH(auth),
2514
                                        TAG_END());
2515
                        } else if(status >= 400) {
2516
                                /* Authentication failed? */
2517
                                session->account.registration_status = janus_sip_registration_status_failed;
2518
                                /* Tell the browser... */
2519
                                json_t *event = json_object();
2520
                                json_object_set_new(event, "sip", json_string("event"));
2521
                                json_t *result = json_object();
2522
                                json_object_set_new(result, "event", json_string("registration_failed"));
2523
                                json_object_set_new(result, "code", json_integer(status));
2524
                                json_object_set_new(result, "reason", json_string(phrase ? phrase : ""));
2525
                                json_object_set_new(event, "result", result);
2526
                                int ret = gateway->push_event(session->handle, &janus_sip_plugin, session->transaction, event, NULL);
2527
                                JANUS_LOG(LOG_VERB, "  >> Pushing event to peer: %d (%s)\n", ret, janus_get_api_error(ret));
2528
                                json_decref(event);
2529
                        }
2530
                        break;
2531
                }
2532
                default:
2533
                        /* unknown event -> print out error message */
2534
                        JANUS_LOG(LOG_ERR, "Unknown event %d (%s)\n", event, nua_event_name(event));
2535
                        break;
2536
        }
2537
}
2538

    
2539
void janus_sip_sdp_process(janus_sip_session *session, janus_sdp *sdp, gboolean answer) {
2540
        if(!session || !sdp)
2541
                return;
2542
        /* c= */
2543
        if(sdp->c_addr) {
2544
                g_free(session->media.remote_ip);
2545
                session->media.remote_ip = g_strdup(sdp->c_addr);
2546
                JANUS_LOG(LOG_VERB, "  >> Media connection:\n");
2547
                JANUS_LOG(LOG_VERB, "       %s\n", session->media.remote_ip);
2548
        }
2549
        JANUS_LOG(LOG_VERB, "  >> Media lines:\n");
2550
        GList *temp = sdp->m_lines;
2551
        while(temp) {
2552
                janus_sdp_mline *m = (janus_sdp_mline *)temp->data;
2553
                session->media.require_srtp = session->media.require_srtp || (m->proto && !strcasecmp(m->proto, "RTP/SAVP"));
2554
                if(m->type == JANUS_SDP_AUDIO) {
2555
                        JANUS_LOG(LOG_VERB, "       Audio: %"SCNu16"\n", m->port);
2556
                        if(m->port) {
2557
                                session->media.has_audio = 1;
2558
                                session->media.remote_audio_rtp_port = m->port;
2559
                                session->media.remote_audio_rtcp_port = m->port+1;        /* FIXME We're assuming RTCP is on the next port */
2560
                        }
2561
                } else if(m->type == JANUS_SDP_VIDEO) {
2562
                        JANUS_LOG(LOG_VERB, "       Video: %"SCNu16"\n", m->port);
2563
                        if(m->port) {
2564
                                session->media.has_video = 1;
2565
                                session->media.remote_video_rtp_port = m->port;
2566
                                session->media.remote_video_rtcp_port = m->port+1;        /* FIXME We're assuming RTCP is on the next port */
2567
                        }
2568
                } else {
2569
                        JANUS_LOG(LOG_WARN, "       Unsupported media line (not audio/video)\n");
2570
                        temp = temp->next;
2571
                        continue;
2572
                }
2573
                JANUS_LOG(LOG_VERB, "       Media connections:\n");
2574
                if(m->c_addr) {
2575
                        g_free(session->media.remote_ip);
2576
                        session->media.remote_ip = g_strdup(m->c_addr);
2577
                        JANUS_LOG(LOG_VERB, "         [%s]\n", session->media.remote_ip);
2578
                }
2579
                JANUS_LOG(LOG_VERB, "       Media attributes:\n");
2580
                GList *tempA = m->attributes;
2581
                while(tempA) {
2582
                        janus_sdp_attribute *a = (janus_sdp_attribute *)tempA->data;
2583
                        if(a->name) {
2584
                                if(!strcasecmp(a->name, "rtpmap")) {
2585
                                        JANUS_LOG(LOG_VERB, "         RTP Map:     %s\n", a->value);
2586
                                } else if(!strcasecmp(a->name, "crypto")) {
2587
                                        JANUS_LOG(LOG_VERB, "         Crypto:      %s\n", a->value);
2588
                                        if(m->type == JANUS_SDP_AUDIO || m->type == JANUS_SDP_VIDEO) {
2589
                                                gint32 tag = 0;
2590
                                                int suite;
2591
                                                char crypto[81];
2592
                                                /* FIXME inline can be more complex than that, and we're currently only offering SHA1_80 */
2593
                                                int res = sscanf(a->value, "%"SCNi32" AES_CM_128_HMAC_SHA1_%2d inline:%80s",
2594
                                                        &tag, &suite, crypto);
2595
                                                if(res != 3) {
2596
                                                        JANUS_LOG(LOG_WARN, "Failed to parse crypto line, ignoring... %s\n", a->value);
2597
                                                } else {
2598
                                                        gboolean video = (m->type == JANUS_SDP_VIDEO);
2599
                                                        int current_suite = video ? session->media.video_srtp_suite_in : session->media.audio_srtp_suite_in;
2600
                                                        if(current_suite == 0) {
2601
                                                                if(video)
2602
                                                                        session->media.video_srtp_suite_in = suite;
2603
                                                                else
2604
                                                                        session->media.audio_srtp_suite_in = suite;
2605
                                                                janus_sip_srtp_set_remote(session, video, crypto, suite);
2606
                                                                session->media.has_srtp_remote = TRUE;
2607
                                                        } else {
2608
                                                                JANUS_LOG(LOG_WARN, "We already configured a %s crypto context (AES_CM_128_HMAC_SHA1_%d), skipping additional crypto line\n",
2609
                                                                        video ? "video" : "audio", current_suite);
2610
                                                        }
2611
                                                }
2612
                                        }
2613
                                }
2614
                        }
2615
                        tempA = tempA->next;
2616
                }
2617
                if(answer && (m->type == JANUS_SDP_AUDIO || m->type == JANUS_SDP_VIDEO)) {
2618
                        /* Check which codec was negotiated eventually */
2619
                        int pt = -1;
2620
                        if(m->ptypes)
2621
                                pt = GPOINTER_TO_INT(m->ptypes->data);
2622
                        if(pt > -1) {
2623
                                if(m->type == JANUS_SDP_AUDIO) {
2624
                                        session->media.audio_pt = pt;
2625
                                } else {
2626
                                        session->media.video_pt = pt;
2627
                                }
2628
                        }
2629
                }
2630
                temp = temp->next;
2631
        }
2632
}
2633

    
2634
char *janus_sip_sdp_manipulate(janus_sip_session *session, janus_sdp *sdp, gboolean answer) {
2635
        if(!session || !session->stack || !sdp)
2636
                return NULL;
2637
        /* Start replacing stuff */
2638
        JANUS_LOG(LOG_VERB, "Setting protocol to %s\n", session->media.require_srtp ? "RTP/SAVP" : "RTP/AVP");
2639
        GList *temp = sdp->m_lines;
2640
        while(temp) {
2641
                janus_sdp_mline *m = (janus_sdp_mline *)temp->data;
2642
                g_free(m->proto);
2643
                m->proto = g_strdup(session->media.require_srtp ? "RTP/SAVP" : "RTP/AVP");
2644
                if(m->type == JANUS_SDP_AUDIO) {
2645
                        m->port = session->media.local_audio_rtp_port;
2646
                        if(session->media.has_srtp_local) {
2647
                                char *crypto = NULL;
2648
                                session->media.audio_srtp_suite_out = 80;
2649
                                janus_sip_srtp_set_local(session, FALSE, &crypto);
2650
                                /* FIXME 32? 80? Both? */
2651
                                janus_sdp_attribute *a = janus_sdp_attribute_create("crypto", "1 AES_CM_128_HMAC_SHA1_80 inline:%s", crypto);
2652
                                g_free(crypto);
2653
                                m->attributes = g_list_append(m->attributes, a);
2654
                        }
2655
                } else if(m->type == JANUS_SDP_VIDEO) {
2656
                        m->port = session->media.local_video_rtp_port;
2657
                        if(session->media.has_srtp_local) {
2658
                                char *crypto = NULL;
2659
                                session->media.audio_srtp_suite_out = 80;
2660
                                janus_sip_srtp_set_local(session, TRUE, &crypto);
2661
                                /* FIXME 32? 80? Both? */
2662
                                janus_sdp_attribute *a = janus_sdp_attribute_create("crypto", "1 AES_CM_128_HMAC_SHA1_80 inline:%s", crypto);
2663
                                g_free(crypto);
2664
                                m->attributes = g_list_append(m->attributes, a);
2665
                        }
2666
                }
2667
                g_free(m->c_addr);
2668
                m->c_addr = g_strdup(local_ip);
2669
                if(answer && (m->type == JANUS_SDP_AUDIO || m->type == JANUS_SDP_VIDEO)) {
2670
                        /* Check which codec was negotiated eventually */
2671
                        int pt = -1;
2672
                        if(m->ptypes)
2673
                                pt = GPOINTER_TO_INT(m->ptypes->data);
2674
                        if(pt > -1) {
2675
                                if(m->type == JANUS_SDP_AUDIO) {
2676
                                        session->media.audio_pt = pt;
2677
                                } else {
2678
                                        session->media.video_pt = pt;
2679
                                }
2680
                        }
2681
                }
2682
                temp = temp->next;
2683
        }
2684
        /* Generate a SDP string out of our changes */
2685
        return janus_sdp_write(sdp);
2686
}
2687

    
2688
/* Bind local RTP/RTCP sockets */
2689
static int janus_sip_allocate_local_ports(janus_sip_session *session) {
2690
        if(session == NULL) {
2691
                JANUS_LOG(LOG_ERR, "Invalid session\n");
2692
                return -1;
2693
        }
2694
        /* Reset status */
2695
        if(session->media.audio_rtp_fd != -1) {
2696
                close(session->media.audio_rtp_fd);
2697
                session->media.audio_rtp_fd = -1;
2698
        }
2699
        if(session->media.audio_rtcp_fd != -1) {
2700
                close(session->media.audio_rtcp_fd);
2701
                session->media.audio_rtcp_fd = -1;
2702
        }
2703
        session->media.local_audio_rtp_port = 0;
2704
        session->media.local_audio_rtcp_port = 0;
2705
        session->media.audio_ssrc = 0;
2706
        if(session->media.video_rtp_fd != -1) {
2707
                close(session->media.video_rtp_fd);
2708
                session->media.video_rtp_fd = -1;
2709
        }
2710
        if(session->media.video_rtcp_fd != -1) {
2711
                close(session->media.video_rtcp_fd);
2712
                session->media.video_rtcp_fd = -1;
2713
        }
2714
        session->media.local_video_rtp_port = 0;
2715
        session->media.local_video_rtcp_port = 0;
2716
        session->media.video_ssrc = 0;
2717
        /* Start */
2718
        int attempts = 100;        /* FIXME Don't retry forever */
2719
        if(session->media.has_audio) {
2720
                JANUS_LOG(LOG_VERB, "Allocating audio ports:\n");
2721
                struct sockaddr_in audio_rtp_address, audio_rtcp_address;
2722
                while(session->media.local_audio_rtp_port == 0 || session->media.local_audio_rtcp_port == 0) {
2723
                        if(attempts == 0)        /* Too many failures */
2724
                                return -1;
2725
                        if(session->media.audio_rtp_fd == -1) {
2726
                                session->media.audio_rtp_fd = socket(AF_INET, SOCK_DGRAM, 0);
2727
                        }
2728
                        if(session->media.audio_rtcp_fd == -1) {
2729
                                session->media.audio_rtcp_fd = socket(AF_INET, SOCK_DGRAM, 0);
2730
                        }
2731
                        int rtp_port = g_random_int_range(10000, 60000);        /* FIXME Should this be configurable? */
2732
                        if(rtp_port % 2)
2733
                                rtp_port++;        /* Pick an even port for RTP */
2734
                        audio_rtp_address.sin_family = AF_INET;
2735
                        audio_rtp_address.sin_port = htons(rtp_port);
2736
                        inet_pton(AF_INET, local_ip, &audio_rtp_address.sin_addr.s_addr);
2737
                        if(bind(session->media.audio_rtp_fd, (struct sockaddr *)(&audio_rtp_address), sizeof(struct sockaddr)) < 0) {
2738
                                JANUS_LOG(LOG_ERR, "Bind failed for audio RTP (port %d), trying a different one...\n", rtp_port);
2739
                                attempts--;
2740
                                continue;
2741
                        }
2742
                        JANUS_LOG(LOG_VERB, "Audio RTP listener bound to port %d\n", rtp_port);
2743
                        int rtcp_port = rtp_port+1;
2744
                        audio_rtcp_address.sin_family = AF_INET;
2745
                        audio_rtcp_address.sin_port = htons(rtcp_port);
2746
                        inet_pton(AF_INET, local_ip, &audio_rtcp_address.sin_addr.s_addr);
2747
                        if(bind(session->media.audio_rtcp_fd, (struct sockaddr *)(&audio_rtcp_address), sizeof(struct sockaddr)) < 0) {
2748
                                JANUS_LOG(LOG_ERR, "Bind failed for audio RTCP (port %d), trying a different one...\n", rtcp_port);
2749
                                /* RTP socket is not valid anymore, reset it */
2750
                                close(session->media.audio_rtp_fd);
2751
                                session->media.audio_rtp_fd = -1;
2752
                                attempts--;
2753
                                continue;
2754
                        }
2755
                        JANUS_LOG(LOG_VERB, "Audio RTCP listener bound to port %d\n", rtcp_port);
2756
                        session->media.local_audio_rtp_port = rtp_port;
2757
                        session->media.local_audio_rtcp_port = rtcp_port;
2758
                }
2759
        }
2760
        if(session->media.has_video) {
2761
                JANUS_LOG(LOG_VERB, "Allocating video ports:\n");
2762
                struct sockaddr_in video_rtp_address, video_rtcp_address;
2763
                while(session->media.local_video_rtp_port == 0 || session->media.local_video_rtcp_port == 0) {
2764
                        if(attempts == 0)        /* Too many failures */
2765
                                return -1;
2766
                        if(session->media.video_rtp_fd == -1) {
2767
                                session->media.video_rtp_fd = socket(AF_INET, SOCK_DGRAM, 0);
2768
                        }
2769
                        if(session->media.video_rtcp_fd == -1) {
2770
                                session->media.video_rtcp_fd = socket(AF_INET, SOCK_DGRAM, 0);
2771
                        }
2772
                        int rtp_port = g_random_int_range(10000, 60000);        /* FIXME Should this be configurable? */
2773
                        if(rtp_port % 2)
2774
                                rtp_port++;        /* Pick an even port for RTP */
2775
                        video_rtp_address.sin_family = AF_INET;
2776
                        video_rtp_address.sin_port = htons(rtp_port);
2777
                        inet_pton(AF_INET, local_ip, &video_rtp_address.sin_addr.s_addr);
2778
                        if(bind(session->media.video_rtp_fd, (struct sockaddr *)(&video_rtp_address), sizeof(struct sockaddr)) < 0) {
2779
                                JANUS_LOG(LOG_ERR, "Bind failed for video RTP (port %d), trying a different one...\n", rtp_port);
2780
                                attempts--;
2781
                                continue;
2782
                        }
2783
                        JANUS_LOG(LOG_VERB, "Video RTP listener bound to port %d\n", rtp_port);
2784
                        int rtcp_port = rtp_port+1;
2785
                        video_rtcp_address.sin_family = AF_INET;
2786
                        video_rtcp_address.sin_port = htons(rtcp_port);
2787
                        inet_pton(AF_INET, local_ip, &video_rtcp_address.sin_addr.s_addr);
2788
                        if(bind(session->media.video_rtcp_fd, (struct sockaddr *)(&video_rtcp_address), sizeof(struct sockaddr)) < 0) {
2789
                                JANUS_LOG(LOG_ERR, "Bind failed for video RTCP (port %d), trying a different one...\n", rtcp_port);
2790
                                /* RTP socket is not valid anymore, reset it */
2791
                                close(session->media.video_rtp_fd);
2792
                                session->media.video_rtp_fd = -1;
2793
                                attempts--;
2794
                                continue;
2795
                        }
2796
                        JANUS_LOG(LOG_VERB, "Video RTCP listener bound to port %d\n", rtcp_port);
2797
                        session->media.local_video_rtp_port = rtp_port;
2798
                        session->media.local_video_rtcp_port = rtcp_port;
2799
                }
2800
        }
2801
        return 0;
2802
}
2803

    
2804
/* Thread to relay RTP/RTCP frames coming from the SIP peer */
2805
static void *janus_sip_relay_thread(void *data) {
2806
        janus_sip_session *session = (janus_sip_session *)data;
2807
        if(!session || !session->account.username || !session->callee) {
2808
                g_thread_unref(g_thread_self());
2809
                return NULL;
2810
        }
2811
        JANUS_LOG(LOG_VERB, "Starting relay thread (%s <--> %s)\n", session->account.username, session->callee);
2812

    
2813
        gboolean have_server_ip = TRUE;
2814
        struct sockaddr_in server_addr;
2815
        memset(&server_addr, 0, sizeof(server_addr));
2816
        server_addr.sin_family = AF_INET;
2817
        if((inet_aton(session->media.remote_ip, &server_addr.sin_addr)) <= 0) {        /* Not a numeric IP... */
2818
                struct hostent *host = gethostbyname(session->media.remote_ip);        /* ...resolve name */
2819
                if(!host) {
2820
                        JANUS_LOG(LOG_ERR, "[SIP-%s] Couldn't get host (%s)\n", session->account.username, session->media.remote_ip);
2821
                        have_server_ip = FALSE;
2822
                } else {
2823
                        server_addr.sin_addr = *(struct in_addr *)host->h_addr_list;
2824
                }
2825
        }
2826

    
2827
        /* Connect peers (FIXME This pretty much sucks right now) */
2828
        if(have_server_ip && session->media.remote_audio_rtp_port) {
2829
                server_addr.sin_port = htons(session->media.remote_audio_rtp_port);
2830
                if(connect(session->media.audio_rtp_fd, (struct sockaddr *)&server_addr, sizeof(struct sockaddr)) == -1) {
2831
                        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);
2832
                        JANUS_LOG(LOG_ERR, "[SIP-%s]   -- %d (%s)\n", session->account.username, errno, strerror(errno));
2833
                }
2834
        }
2835
        if(have_server_ip && session->media.remote_audio_rtcp_port) {
2836
                server_addr.sin_port = htons(session->media.remote_audio_rtcp_port);
2837
                if(connect(session->media.audio_rtcp_fd, (struct sockaddr *)&server_addr, sizeof(struct sockaddr)) == -1) {
2838
                        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);
2839
                        JANUS_LOG(LOG_ERR, "[SIP-%s]   -- %d (%s)\n", session->account.username, errno, strerror(errno));
2840
                }
2841
        }
2842
        if(have_server_ip && session->media.remote_video_rtp_port) {
2843
                server_addr.sin_port = htons(session->media.remote_video_rtp_port);
2844
                if(connect(session->media.video_rtp_fd, (struct sockaddr *)&server_addr, sizeof(struct sockaddr)) == -1) {
2845
                        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);
2846
                        JANUS_LOG(LOG_ERR, "[SIP-%s]   -- %d (%s)\n", session->account.username, errno, strerror(errno));
2847
                }
2848
        }
2849
        if(have_server_ip && session->media.remote_video_rtcp_port) {
2850
                server_addr.sin_port = htons(session->media.remote_video_rtcp_port);
2851
                if(connect(session->media.video_rtcp_fd, (struct sockaddr *)&server_addr, sizeof(struct sockaddr)) == -1) {
2852
                        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);
2853
                        JANUS_LOG(LOG_ERR, "[SIP-%s]   -- %d (%s)\n", session->account.username, errno, strerror(errno));
2854
                }
2855
        }
2856

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

    
3069

    
3070
/* Sofia Event thread */
3071
gpointer janus_sip_sofia_thread(gpointer user_data) {
3072
        janus_sip_session *session = (janus_sip_session *)user_data;
3073
        if(session == NULL || session->account.username == NULL) {
3074
                g_thread_unref(g_thread_self());
3075
                return NULL;
3076
        }
3077
        JANUS_LOG(LOG_VERB, "Joining sofia loop thread (%s)...\n", session->account.username);
3078
        session->stack = g_malloc0(sizeof(ssip_t));
3079
        session->stack->session = session;
3080
        session->stack->s_nua = NULL;
3081
        session->stack->s_nh_r = NULL;
3082
        session->stack->s_nh_i = NULL;
3083
        session->stack->s_root = su_root_create(session->stack);
3084
        su_home_init(session->stack->s_home);
3085
        JANUS_LOG(LOG_VERB, "Setting up sofia stack (sip:%s@%s)\n", session->account.username, local_ip);
3086
        char sip_url[128];
3087
        char sips_url[128];
3088
        char *ipv6;
3089
        ipv6 = strstr(local_ip, ":");
3090
        g_snprintf(sip_url, sizeof(sip_url), "sip:%s%s%s:*", ipv6 ? "[" : "", local_ip, ipv6 ? "]" : "");
3091
        g_snprintf(sips_url, sizeof(sips_url), "sips:%s%s%s:*", ipv6 ? "[" : "", local_ip, ipv6 ? "]" : "");
3092
        char outbound_options[256] = "use-rport no-validate";
3093
        if(keepalive_interval > 0)
3094
                g_strlcat(outbound_options, " options-keepalive", sizeof(outbound_options));
3095
        if(!behind_nat)
3096
                g_strlcat(outbound_options, " no-natify", sizeof(outbound_options));
3097
        session->stack->s_nua = nua_create(session->stack->s_root,
3098
                                janus_sip_sofia_callback,
3099
                                session,
3100
                                SIPTAG_ALLOW_STR("INVITE, ACK, BYE, CANCEL, OPTIONS"),
3101
                                NUTAG_M_USERNAME(session->account.username),
3102
                                NUTAG_URL(sip_url),
3103
                                TAG_IF(session->account.sips, NUTAG_SIPS_URL(sips_url)),
3104
                                SIPTAG_USER_AGENT_STR(session->account.user_agent ? session->account.user_agent : user_agent),
3105
                                NUTAG_KEEPALIVE(keepalive_interval * 1000),        /* Sofia expects it in milliseconds */
3106
                                NUTAG_OUTBOUND(outbound_options),
3107
                                SIPTAG_SUPPORTED(NULL),
3108
                                TAG_NULL());
3109
        su_root_run(session->stack->s_root);
3110
        /* When we get here, we're done */
3111
        nua_destroy(session->stack->s_nua);
3112
        su_root_destroy(session->stack->s_root);
3113
        session->stack->s_root = NULL;
3114
        su_home_deinit(session->stack->s_home);
3115
        su_home_unref(session->stack->s_home);
3116
        if (session->stack) {
3117
                g_free(session->stack);
3118
                session->stack = NULL;
3119
        }
3120
        //~ stop = 1;
3121
        JANUS_LOG(LOG_VERB, "Leaving sofia loop thread...\n");
3122
        g_thread_unref(g_thread_self());
3123
        /* Cleaning up and removing the session is done in a lazy way */
3124
        janus_mutex_lock(&sessions_mutex);
3125
        old_sessions = g_list_append(old_sessions, session);
3126
        janus_mutex_unlock(&sessions_mutex);
3127
        return NULL;
3128
}