Statistics
| Branch: | Revision:

janus-gateway / plugins / janus_sip.c @ 71a04f89

History | View | Annotate | Download (137 KB)

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

    
51
#include "plugin.h"
52

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

    
56
#include <jansson.h>
57

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

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

    
69
#include "../debug.h"
70
#include "../apierror.h"
71
#include "../config.h"
72
#include "../mutex.h"
73
#include "../record.h"
74
#include "../rtp.h"
75
#include "../rtcp.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, char *message, char *sdp_type, char *sdp);
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
char *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 gboolean notify_events = TRUE;
178
static janus_callbacks *gateway = NULL;
179

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

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

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

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

    
205
        msg->handle = NULL;
206

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

    
216
        g_free(msg);
217
}
218

    
219

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

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

    
248

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

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

    
274

    
275
/* Sofia stuff */
276
typedef struct ssip_s ssip_t;
277
typedef struct ssip_oper_s ssip_oper_t;
278

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

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

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

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

    
350

    
351
#undef SU_ROOT_MAGIC_T
352
#define SU_ROOT_MAGIC_T        ssip_t
353
#undef NUA_MAGIC_T
354
#define NUA_MAGIC_T                ssip_t
355
#undef NUA_HMAGIC_T
356
#define NUA_HMAGIC_T        ssip_oper_t
357

    
358
struct ssip_s {
359
        su_home_t s_home[1];
360
        su_root_t *s_root;
361
        nua_t *s_nua;
362
        nua_handle_t *s_nh_r, *s_nh_i;
363
        janus_sip_session *session;
364
};
365

    
366

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

    
507

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

    
519

    
520
/* URI parsing utilies */
521

    
522
#define JANUS_SIP_URI_MAXLEN        1024
523
typedef struct {
524
        char data[JANUS_SIP_URI_MAXLEN];
525
        url_t url[1];
526
} janus_sip_uri_t;
527

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

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

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

    
560

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

    
648

    
649
static void janus_sip_detect_local_ip(char *buf, size_t buflen) {
650
        JANUS_LOG(LOG_VERB, "Autodetecting local IP...\n");
651

    
652
        struct sockaddr_in addr;
653
        socklen_t len;
654
        int fd = socket(AF_INET, SOCK_DGRAM, 0);
655
        if (fd == -1)
656
                goto error;
657
        addr.sin_family = AF_INET;
658
        addr.sin_port = htons(1);
659
        inet_pton(AF_INET, "1.2.3.4", &addr.sin_addr.s_addr);
660
        if (connect(fd, (const struct sockaddr*) &addr, sizeof(addr)) < 0)
661
                goto error;
662
        len = sizeof(addr);
663
        if (getsockname(fd, (struct sockaddr*) &addr, &len) < 0)
664
                goto error;
665
        if (getnameinfo((const struct sockaddr*) &addr, sizeof(addr),
666
                        buf, buflen,
667
                        NULL, 0, NI_NUMERICHOST) != 0)
668
                goto error;
669
        close(fd);
670
        return;
671

    
672
error:
673
        if (fd != -1)
674
                close(fd);
675
        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");
676
        g_strlcpy(buf, "127.0.0.1", buflen);
677
}
678

    
679

    
680
/* Random string helper (for call-ids) */
681
static char charset[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
682
static void janus_sip_random_string(int length, char *buffer) {
683
        if(length > 0 && buffer) {
684
                int l = (int)(sizeof(charset)-1);
685
                int i=0;
686
                for(i=0; i<length; i++) {
687
                        int key = rand() % l;
688
                        buffer[i] = charset[key];
689
                }
690
                buffer[length-1] = '\0';
691
        }
692
}
693

    
694

    
695
/* Sofia SIP logger function: when the Event Handlers mechanism is enabled,
696
 * we use this to intercept SIP messages sent by the stack (received
697
 * messages are more easily recoverable in janus_sip_sofia_callback) */
698
char sofia_log[2048];
699
char call_id[255];
700
gboolean skip = FALSE, started = FALSE, append = FALSE;
701
static void janus_sip_sofia_logger(void *stream, char const *fmt, va_list ap) {
702
        if(!fmt)
703
                return;
704
        char line[255];
705
        g_vsnprintf(line, sizeof(line), fmt, ap);
706
        if(skip) {
707
                /* This is a message we're not interested in: just check when it ends */
708
                if(line[3] == '-') {
709
                        skip = FALSE;
710
                        append = FALSE;
711
                }
712
                return;
713
        }
714
        if(append) {
715
                /* We're copying a message in our buffer: check if this is the end */
716
                if(line[3] == '-') {
717
                        if(!started) {
718
                                /* Ok, start appending from now on */
719
                                started = TRUE;
720
                                sofia_log[0] = '\0';
721
                                call_id[0] = '\0';
722
                        } else {
723
                                /* Message ended, handle it */
724
                                skip = FALSE;
725
                                append = FALSE;
726
                                /* Look for the session this message belongs to */
727
                                janus_sip_session *session = NULL;
728
                                if(strlen(call_id))
729
                                        session = g_hash_table_lookup(callids, call_id);
730
                                if(!session) {
731
                                        /* Couldn't find any SIP session with that Call-ID, check the request */
732
                                        if(strstr(sofia_log, "REGISTER") == sofia_log || strstr(sofia_log, "SIP/2.0 ") == sofia_log) {
733
                                                /* FIXME This is a REGISTER or a response code:
734
                                                 * check the To header and get the identity from there */
735
                                                char *from = strstr(sofia_log, "To: ");
736
                                                if(from) {
737
                                                        from = from+4;
738
                                                        char *start = strstr(from, "<");
739
                                                        if(start) {
740
                                                                start++;
741
                                                                char *end = strstr(from, ">");
742
                                                                if(end) {
743
                                                                        *end = '\0';
744
                                                                        g_snprintf(call_id, sizeof(call_id), "%s", start);
745
                                                                        *end = '>';
746
                                                                        session = g_hash_table_lookup(identities, call_id);
747
                                                                }
748
                                                        }
749
                                                }
750
                                        }
751
                                }
752
                                if(session) {
753
                                        /* Notify event handlers about the content of the whole outgoing SIP message */
754
                                        json_t *info = json_object();
755
                                        json_object_set_new(info, "event", json_string("sip-out"));
756
                                        json_object_set_new(info, "sip", json_string(sofia_log));
757
                                        gateway->notify_event(session->handle, info);
758
                                } else {
759
                                        JANUS_LOG(LOG_WARN, "Couldn't find a session associated to this message, dropping it...\n%s", sofia_log);
760
                                }
761
                                /* Done, reset the buffers */
762
                                sofia_log[0] = '\0';
763
                                call_id[0] = '\0';
764
                        }
765
                        return;
766
                }
767
                if(strlen(line) == 1) {
768
                        /* Append a carriage and return */
769
                        g_strlcat(sofia_log, "\r\n", sizeof(sofia_log));
770
                } else {
771
                        /* If this is an OPTIONS, we don't care: drop it */
772
                        char *header = &line[3];
773
                        if(strstr(header, "OPTIONS") == header) {
774
                                skip = TRUE;
775
                                return;
776
                        }
777
                        /* Is this a Call-ID header? Keep note of it */
778
                        if(strstr(header, "Call-ID") == header) {
779
                                g_snprintf(call_id, sizeof(call_id), "%s", header+9);
780
                        }
781
                        /* Append the line to our buffer, skipping the indent */
782
                        g_strlcat(sofia_log, &line[3], sizeof(sofia_log));
783
                }
784
                return;
785
        }
786
        /* Still waiting to decide if this is a message we need */
787
        if(line[0] == 's' && line[1] == 'e' && line[2] == 'n' && line[3] == 'd' && line[4] == ' ') {
788
                /* An outgoing message is going to be logged, prepare for that */
789
                skip = FALSE;
790
                started = FALSE;
791
                append = TRUE;
792
                int length = atoi(&line[5]);
793
                JANUS_LOG(LOG_HUGE, "Intercepting message (%d bytes)\n", length);
794
                if(strstr(line, "-----"))
795
                        started = TRUE;
796
        }
797
}
798

    
799

    
800
/* Plugin implementation */
801
int janus_sip_init(janus_callbacks *callback, const char *config_path) {
802
        if(g_atomic_int_get(&stopping)) {
803
                /* Still stopping from before */
804
                return -1;
805
        }
806
        if(callback == NULL || config_path == NULL) {
807
                /* Invalid arguments */
808
                return -1;
809
        }
810

    
811
        /* Read configuration */
812
        char filename[255];
813
        g_snprintf(filename, 255, "%s/%s.cfg", config_path, JANUS_SIP_PACKAGE);
814
        JANUS_LOG(LOG_VERB, "Configuration file: %s\n", filename);
815
        janus_config *config = janus_config_parse(filename);
816
        if(config != NULL) {
817
                janus_config_print(config);
818

    
819
                gboolean local_ip_set = FALSE;
820
                janus_config_item *item = janus_config_get_item_drilldown(config, "general", "local_ip");
821
                if(item && item->value) {
822
                        int family;
823
                        if (!janus_is_ip_valid(item->value, &family)) {
824
                                JANUS_LOG(LOG_WARN, "Invalid local IP specified: %s, guessing the default...\n", item->value);
825
                        } else {
826
                                /* Verify that we can actually bind to that address */
827
                                int fd = socket(family, SOCK_DGRAM, 0);
828
                                if (fd == -1) {
829
                                        JANUS_LOG(LOG_WARN, "Error creating test socket, falling back to detecting IP address...\n");
830
                                } else {
831
                                        int r;
832
                                        struct sockaddr_storage ss;
833
                                        socklen_t addrlen;
834
                                        memset(&ss, 0, sizeof(ss));
835
                                        if (family == AF_INET) {
836
                                                struct sockaddr_in *addr4 = (struct sockaddr_in*)&ss;
837
                                                addr4->sin_family = AF_INET;
838
                                                addr4->sin_port = 0;
839
                                                inet_pton(AF_INET, item->value, &(addr4->sin_addr.s_addr));
840
                                                addrlen = sizeof(struct sockaddr_in);
841
                                        } else {
842
                                                struct sockaddr_in6 *addr6 = (struct sockaddr_in6*)&ss;
843
                                                addr6->sin6_family = AF_INET6;
844
                                                addr6->sin6_port = 0;
845
                                                inet_pton(AF_INET6, item->value, &(addr6->sin6_addr.s6_addr));
846
                                                addrlen = sizeof(struct sockaddr_in6);
847
                                        }
848
                                        r = bind(fd, (const struct sockaddr*)&ss, addrlen);
849
                                        close(fd);
850
                                        if (r < 0) {
851
                                                JANUS_LOG(LOG_WARN, "Error setting local IP address to %s, falling back to detecting IP address...\n", item->value);
852
                                        } else {
853
                                                g_strlcpy(local_ip, item->value, sizeof(local_ip));
854
                                                local_ip_set = TRUE;
855
                                        }
856
                                }
857
                        }
858
                }
859
                if (!local_ip_set)
860
                        janus_sip_detect_local_ip(local_ip, sizeof(local_ip));
861
                JANUS_LOG(LOG_VERB, "Local IP set to %s\n", local_ip);
862

    
863
                item = janus_config_get_item_drilldown(config, "general", "keepalive_interval");
864
                if(item && item->value)
865
                        keepalive_interval = atoi(item->value);
866
                JANUS_LOG(LOG_VERB, "SIP keep-alive interval set to %d seconds\n", keepalive_interval);
867

    
868
                item = janus_config_get_item_drilldown(config, "general", "register_ttl");
869
                if(item && item->value)
870
                        register_ttl = atoi(item->value);
871
                JANUS_LOG(LOG_VERB, "SIP registration TTL set to %d seconds\n", register_ttl);
872

    
873
                item = janus_config_get_item_drilldown(config, "general", "behind_nat");
874
                if(item && item->value)
875
                        behind_nat = janus_is_true(item->value);
876

    
877
                item = janus_config_get_item_drilldown(config, "general", "user_agent");
878
                if(item && item->value)
879
                        user_agent = g_strdup(item->value);
880
                else
881
                        user_agent = g_strdup("Janus WebRTC Gateway SIP Plugin "JANUS_SIP_VERSION_STRING);
882
                JANUS_LOG(LOG_VERB, "SIP User-Agent set to %s\n", user_agent);
883

    
884
                item = janus_config_get_item_drilldown(config, "general", "events");
885
                if(item != NULL && item->value != NULL)
886
                        notify_events = janus_is_true(item->value);
887
                if(!notify_events && callback->events_is_enabled()) {
888
                        JANUS_LOG(LOG_WARN, "Notification of events to handlers disabled for %s\n", JANUS_SIP_NAME);
889
                }
890

    
891
                janus_config_destroy(config);
892
        }
893
        config = NULL;
894

    
895
        /* Setup sofia */
896
        su_init();
897
        if(callback->events_is_enabled()) {
898
                /* Enable the transport logging, as we want to have access to the SIP messages */
899
                setenv("TPORT_LOG", "1", 1);
900
                su_log_redirect(NULL, janus_sip_sofia_logger, NULL);
901
        }
902

    
903
        sessions = g_hash_table_new(NULL, NULL);
904
        callids = g_hash_table_new(g_str_hash, g_str_equal);
905
        identities = g_hash_table_new(g_str_hash, g_str_equal);
906
        janus_mutex_init(&sessions_mutex);
907
        messages = g_async_queue_new_full((GDestroyNotify) janus_sip_message_free);
908
        /* This is the callback we'll need to invoke to contact the gateway */
909
        gateway = callback;
910

    
911
        g_atomic_int_set(&initialized, 1);
912

    
913
        GError *error = NULL;
914
        /* Start the sessions watchdog */
915
        watchdog = g_thread_try_new("etest watchdog", &janus_sip_watchdog, NULL, &error);
916
        if(error != NULL) {
917
                g_atomic_int_set(&initialized, 0);
918
                JANUS_LOG(LOG_ERR, "Got error %d (%s) trying to launch the SIP watchdog thread...\n", error->code, error->message ? error->message : "??");
919
                return -1;
920
        }
921
        /* Launch the thread that will handle incoming messages */
922
        handler_thread = g_thread_try_new("janus sip handler", janus_sip_handler, NULL, &error);
923
        if(error != NULL) {
924
                g_atomic_int_set(&initialized, 0);
925
                JANUS_LOG(LOG_ERR, "Got error %d (%s) trying to launch the SIP handler thread...\n", error->code, error->message ? error->message : "??");
926
                return -1;
927
        }
928
        JANUS_LOG(LOG_INFO, "%s initialized!\n", JANUS_SIP_NAME);
929
        return 0;
930
}
931

    
932
void janus_sip_destroy(void) {
933
        if(!g_atomic_int_get(&initialized))
934
                return;
935
        g_atomic_int_set(&stopping, 1);
936

    
937
        g_async_queue_push(messages, &exit_message);
938
        if(handler_thread != NULL) {
939
                g_thread_join(handler_thread);
940
                handler_thread = NULL;
941
        }
942
        if(watchdog != NULL) {
943
                g_thread_join(watchdog);
944
                watchdog = NULL;
945
        }
946
        /* FIXME We should destroy the sessions cleanly */
947
        janus_mutex_lock(&sessions_mutex);
948
        g_hash_table_destroy(sessions);
949
        g_hash_table_destroy(callids);
950
        g_hash_table_destroy(identities);
951
        sessions = NULL;
952
        callids = NULL;
953
        identities = NULL;
954
        janus_mutex_unlock(&sessions_mutex);
955
        g_async_queue_unref(messages);
956
        messages = NULL;
957
        g_atomic_int_set(&initialized, 0);
958
        g_atomic_int_set(&stopping, 0);
959
        JANUS_LOG(LOG_INFO, "%s destroyed!\n", JANUS_SIP_NAME);
960
}
961

    
962
int janus_sip_get_api_compatibility(void) {
963
        /* Important! This is what your plugin MUST always return: don't lie here or bad things will happen */
964
        return JANUS_PLUGIN_API_VERSION;
965
}
966

    
967
int janus_sip_get_version(void) {
968
        return JANUS_SIP_VERSION;
969
}
970

    
971
const char *janus_sip_get_version_string(void) {
972
        return JANUS_SIP_VERSION_STRING;
973
}
974

    
975
const char *janus_sip_get_description(void) {
976
        return JANUS_SIP_DESCRIPTION;
977
}
978

    
979
const char *janus_sip_get_name(void) {
980
        return JANUS_SIP_NAME;
981
}
982

    
983
const char *janus_sip_get_author(void) {
984
        return JANUS_SIP_AUTHOR;
985
}
986

    
987
const char *janus_sip_get_package(void) {
988
        return JANUS_SIP_PACKAGE;
989
}
990

    
991
void janus_sip_create_session(janus_plugin_session *handle, int *error) {
992
        if(g_atomic_int_get(&stopping) || !g_atomic_int_get(&initialized)) {
993
                *error = -1;
994
                return;
995
        }
996
        janus_sip_session *session = g_malloc0(sizeof(janus_sip_session));
997
        session->handle = handle;
998
        session->account.identity = NULL;
999
        session->account.sips = TRUE;
1000
        session->account.username = NULL;
1001
        session->account.display_name = NULL;
1002
        session->account.user_agent = NULL;
1003
        session->account.authuser = NULL;
1004
        session->account.secret = NULL;
1005
        session->account.secret_type = janus_sip_secret_type_unknown;
1006
        session->account.sip_port = 0;
1007
        session->account.proxy = NULL;
1008
        session->account.registration_status = janus_sip_registration_status_unregistered;
1009
        session->status = janus_sip_call_status_idle;
1010
        session->stack = NULL;
1011
        session->transaction = NULL;
1012
        session->callee = NULL;
1013
        session->callid = NULL;
1014
        session->media.remote_ip = NULL;
1015
        session->media.ready = 0;
1016
        session->media.autoack = TRUE;
1017
        session->media.require_srtp = FALSE;
1018
        session->media.has_srtp_local = FALSE;
1019
        session->media.has_srtp_remote = FALSE;
1020
        session->media.has_audio = 0;
1021
        session->media.audio_rtp_fd = -1;
1022
        session->media.audio_rtcp_fd= -1;
1023
        session->media.local_audio_rtp_port = 0;
1024
        session->media.remote_audio_rtp_port = 0;
1025
        session->media.local_audio_rtcp_port = 0;
1026
        session->media.remote_audio_rtcp_port = 0;
1027
        session->media.audio_ssrc = 0;
1028
        session->media.audio_ssrc_peer = 0;
1029
        session->media.audio_pt = -1;
1030
        session->media.audio_pt_name = NULL;
1031
        session->media.audio_srtp_suite_in = 0;
1032
        session->media.audio_srtp_suite_out = 0;
1033
        session->media.has_video = 0;
1034
        session->media.video_rtp_fd = -1;
1035
        session->media.video_rtcp_fd= -1;
1036
        session->media.local_video_rtp_port = 0;
1037
        session->media.remote_video_rtp_port = 0;
1038
        session->media.local_video_rtcp_port = 0;
1039
        session->media.remote_video_rtcp_port = 0;
1040
        session->media.video_ssrc = 0;
1041
        session->media.video_ssrc_peer = 0;
1042
        session->media.video_pt = -1;
1043
        session->media.video_pt_name = NULL;
1044
        session->media.video_srtp_suite_in = 0;
1045
        session->media.video_srtp_suite_out = 0;
1046
        janus_mutex_init(&session->rec_mutex);
1047
        session->destroyed = 0;
1048
        g_atomic_int_set(&session->hangingup, 0);
1049
        janus_mutex_init(&session->mutex);
1050
        handle->plugin_handle = session;
1051

    
1052
        janus_mutex_lock(&sessions_mutex);
1053
        g_hash_table_insert(sessions, handle, session);
1054
        janus_mutex_unlock(&sessions_mutex);
1055

    
1056
        return;
1057
}
1058

    
1059
void janus_sip_destroy_session(janus_plugin_session *handle, int *error) {
1060
        if(g_atomic_int_get(&stopping) || !g_atomic_int_get(&initialized)) {
1061
                *error = -1;
1062
                return;
1063
        }
1064
        janus_sip_session *session = (janus_sip_session *)handle->plugin_handle;
1065
        if(!session) {
1066
                JANUS_LOG(LOG_ERR, "No SIP session associated with this handle...\n");
1067
                *error = -2;
1068
                return;
1069
        }
1070
        janus_mutex_lock(&sessions_mutex);
1071
        if(!session->destroyed) {
1072
                g_hash_table_remove(sessions, handle);
1073
                janus_sip_hangup_media(handle);
1074
                session->destroyed = janus_get_monotonic_time();
1075
                JANUS_LOG(LOG_VERB, "Destroying SIP session (%s)...\n", session->account.username ? session->account.username : "unregistered user");
1076
                if(session->stack != NULL) {
1077
                        /* Shutdown the NUA: this will remove the session later on */
1078
                        nua_shutdown(session->stack->s_nua);
1079
                } else {
1080
                        /* No stack, maybe never registered: cleaning up and removing the session is done in a lazy way */
1081
                        old_sessions = g_list_append(old_sessions, session);
1082
                }
1083
        }
1084
        janus_mutex_unlock(&sessions_mutex);
1085
        return;
1086
}
1087

    
1088
char *janus_sip_query_session(janus_plugin_session *handle) {
1089
        if(g_atomic_int_get(&stopping) || !g_atomic_int_get(&initialized)) {
1090
                return NULL;
1091
        }
1092
        janus_sip_session *session = (janus_sip_session *)handle->plugin_handle;
1093
        if(!session) {
1094
                JANUS_LOG(LOG_ERR, "No session associated with this handle...\n");
1095
                return NULL;
1096
        }
1097
        /* Provide some generic info, e.g., if we're in a call and with whom */
1098
        json_t *info = json_object();
1099
        json_object_set_new(info, "username", session->account.username ? json_string(session->account.username) : NULL);
1100
        json_object_set_new(info, "display_name", session->account.display_name ? json_string(session->account.display_name) : NULL);
1101
        json_object_set_new(info, "user_agent", session->account.user_agent ? json_string(session->account.user_agent) : NULL);
1102
        json_object_set_new(info, "identity", session->account.identity ? json_string(session->account.identity) : NULL);
1103
        json_object_set_new(info, "registration_status", json_string(janus_sip_registration_status_string(session->account.registration_status)));
1104
        json_object_set_new(info, "call_status", json_string(janus_sip_call_status_string(session->status)));
1105
        if(session->callee) {
1106
                json_object_set_new(info, "callee", json_string(session->callee ? session->callee : "??"));
1107
                json_object_set_new(info, "auto-ack", json_string(session->media.autoack ? "yes" : "no"));
1108
                json_object_set_new(info, "srtp-required", json_string(session->media.require_srtp ? "yes" : "no"));
1109
                json_object_set_new(info, "sdes-local", json_string(session->media.has_srtp_local ? "yes" : "no"));
1110
                json_object_set_new(info, "sdes-remote", json_string(session->media.has_srtp_remote ? "yes" : "no"));
1111
        }
1112
        if(session->arc || session->vrc || session->arc_peer || session->vrc_peer) {
1113
                json_t *recording = json_object();
1114
                if(session->arc && session->arc->filename)
1115
                        json_object_set_new(recording, "audio", json_string(session->arc->filename));
1116
                if(session->vrc && session->vrc->filename)
1117
                        json_object_set_new(recording, "video", json_string(session->vrc->filename));
1118
                if(session->arc_peer && session->arc_peer->filename)
1119
                        json_object_set_new(recording, "audio-peer", json_string(session->arc_peer->filename));
1120
                if(session->vrc_peer && session->vrc_peer->filename)
1121
                        json_object_set_new(recording, "video-peer", json_string(session->vrc_peer->filename));
1122
                json_object_set_new(info, "recording", recording);
1123
        }
1124
        json_object_set_new(info, "destroyed", json_integer(session->destroyed));
1125
        char *info_text = json_dumps(info, JSON_INDENT(3) | JSON_PRESERVE_ORDER);
1126
        json_decref(info);
1127
        return info_text;
1128
}
1129

    
1130
struct janus_plugin_result *janus_sip_handle_message(janus_plugin_session *handle, char *transaction, char *message, char *sdp_type, char *sdp) {
1131
        if(g_atomic_int_get(&stopping) || !g_atomic_int_get(&initialized))
1132
                return janus_plugin_result_new(JANUS_PLUGIN_ERROR, g_atomic_int_get(&stopping) ? "Shutting down" : "Plugin not initialized");
1133
        JANUS_LOG(LOG_VERB, "%s\n", message);
1134
        janus_sip_message *msg = g_malloc0(sizeof(janus_sip_message));
1135
        msg->handle = handle;
1136
        msg->transaction = transaction;
1137
        msg->message = message;
1138
        msg->sdp_type = sdp_type;
1139
        msg->sdp = sdp;
1140
        g_async_queue_push(messages, msg);
1141

    
1142
        /* All the requests to this plugin are handled asynchronously */
1143
        return janus_plugin_result_new(JANUS_PLUGIN_OK_WAIT, NULL);
1144
}
1145

    
1146
void janus_sip_setup_media(janus_plugin_session *handle) {
1147
        JANUS_LOG(LOG_INFO, "WebRTC media is now available\n");
1148
        if(g_atomic_int_get(&stopping) || !g_atomic_int_get(&initialized))
1149
                return;
1150
        janus_sip_session *session = (janus_sip_session *)handle->plugin_handle;
1151
        if(!session) {
1152
                JANUS_LOG(LOG_ERR, "No session associated with this handle...\n");
1153
                return;
1154
        }
1155
        if(session->destroyed)
1156
                return;
1157
        g_atomic_int_set(&session->hangingup, 0);
1158
        /* TODO Only relay RTP/RTCP when we get this event */
1159
}
1160

    
1161
void janus_sip_incoming_rtp(janus_plugin_session *handle, int video, char *buf, int len) {
1162
        if(handle == NULL || handle->stopped || g_atomic_int_get(&stopping) || !g_atomic_int_get(&initialized))
1163
                return;
1164
        if(gateway) {
1165
                /* Honour the audio/video active flags */
1166
                janus_sip_session *session = (janus_sip_session *)handle->plugin_handle;
1167
                if(!session || session->destroyed) {
1168
                        JANUS_LOG(LOG_ERR, "No session associated with this handle...\n");
1169
                        return;
1170
                }
1171
                if(session->status != janus_sip_call_status_incall)
1172
                        return;
1173
                /* Forward to our SIP peer */
1174
                if(video) {
1175
                        if(session->media.video_ssrc == 0) {
1176
                                rtp_header *header = (rtp_header *)buf;
1177
                                session->media.video_ssrc = ntohl(header->ssrc);
1178
                                JANUS_LOG(LOG_VERB, "Got SIP video SSRC: %"SCNu32"\n", session->media.video_ssrc);
1179
                        }
1180
                        if(session->media.has_video && session->media.video_rtp_fd) {
1181
                                /* Save the frame if we're recording */
1182
                                janus_recorder_save_frame(session->vrc, buf, len);
1183
                                /* Is SRTP involved? */
1184
                                if(session->media.has_srtp_local) {
1185
                                        char sbuf[2048];
1186
                                        memcpy(&sbuf, buf, len);
1187
                                        int protected = len;
1188
                                        int res = srtp_protect(session->media.video_srtp_out, &sbuf, &protected);
1189
                                        if(res != err_status_ok) {
1190
                                                rtp_header *header = (rtp_header *)&sbuf;
1191
                                                guint32 timestamp = ntohl(header->timestamp);
1192
                                                guint16 seq = ntohs(header->seq_number);
1193
                                                JANUS_LOG(LOG_ERR, "[SIP-%s] Video SRTP protect error... %s (len=%d-->%d, ts=%"SCNu32", seq=%"SCNu16")...\n",
1194
                                                        session->account.username, janus_sip_get_srtp_error(res), len, protected, timestamp, seq);
1195
                                        } else {
1196
                                                /* Forward the frame to the peer */
1197
                                                send(session->media.video_rtp_fd, sbuf, protected, 0);
1198
                                        }
1199
                                } else {
1200
                                        /* Forward the frame to the peer */
1201
                                        send(session->media.video_rtp_fd, buf, len, 0);
1202
                                }
1203
                        }
1204
                } else {
1205
                        if(session->media.audio_ssrc == 0) {
1206
                                rtp_header *header = (rtp_header *)buf;
1207
                                session->media.audio_ssrc = ntohl(header->ssrc);
1208
                                JANUS_LOG(LOG_VERB, "Got SIP audio SSRC: %"SCNu32"\n", session->media.audio_ssrc);
1209
                        }
1210
                        if(session->media.has_audio && session->media.audio_rtp_fd) {
1211
                                /* Save the frame if we're recording */
1212
                                janus_recorder_save_frame(session->arc, buf, len);
1213
                                /* Is SRTP involved? */
1214
                                if(session->media.has_srtp_local) {
1215
                                        char sbuf[2048];
1216
                                        memcpy(&sbuf, buf, len);
1217
                                        int protected = len;
1218
                                        int res = srtp_protect(session->media.audio_srtp_out, &sbuf, &protected);
1219
                                        if(res != err_status_ok) {
1220
                                                rtp_header *header = (rtp_header *)&sbuf;
1221
                                                guint32 timestamp = ntohl(header->timestamp);
1222
                                                guint16 seq = ntohs(header->seq_number);
1223
                                                JANUS_LOG(LOG_ERR, "[SIP-%s] Audio SRTP protect error... %s (len=%d-->%d, ts=%"SCNu32", seq=%"SCNu16")...\n",
1224
                                                        session->account.username, janus_sip_get_srtp_error(res), len, protected, timestamp, seq);
1225
                                        } else {
1226
                                                /* Forward the frame to the peer */
1227
                                                send(session->media.audio_rtp_fd, sbuf, protected, 0);
1228
                                        }
1229
                                } else {
1230
                                        /* Forward the frame to the peer */
1231
                                        send(session->media.audio_rtp_fd, buf, len, 0);
1232
                                }
1233
                        }
1234
                }
1235
        }
1236
}
1237

    
1238
void janus_sip_incoming_rtcp(janus_plugin_session *handle, int video, char *buf, int len) {
1239
        if(handle == NULL || handle->stopped || g_atomic_int_get(&stopping) || !g_atomic_int_get(&initialized))
1240
                return;
1241
        if(gateway) {
1242
                janus_sip_session *session = (janus_sip_session *)handle->plugin_handle;
1243
                if(!session || session->destroyed) {
1244
                        JANUS_LOG(LOG_ERR, "No session associated with this handle...\n");
1245
                        return;
1246
                }
1247
                if(session->status != janus_sip_call_status_incall)
1248
                        return;
1249
                /* Forward to our SIP peer */
1250
                if(video) {
1251
                        if(session->media.has_video && session->media.video_rtcp_fd) {
1252
                                /* Is SRTP involved? */
1253
                                if(session->media.has_srtp_local) {
1254
                                        char sbuf[2048];
1255
                                        memcpy(&sbuf, buf, len);
1256
                                        int protected = len;
1257
                                        int res = srtp_protect_rtcp(session->media.video_srtp_out, &sbuf, &protected);
1258
                                        if(res != err_status_ok) {
1259
                                                JANUS_LOG(LOG_ERR, "[SIP-%s] Video SRTCP protect error... %s (len=%d-->%d)...\n",
1260
                                                        session->account.username, janus_sip_get_srtp_error(res), len, protected);
1261
                                        } else {
1262
                                                /* Fix SSRCs as the gateway does */
1263
                                                JANUS_LOG(LOG_HUGE, "[SIP] Fixing SSRCs (local %u, peer %u)\n",
1264
                                                        session->media.video_ssrc, session->media.video_ssrc_peer);
1265
                                                janus_rtcp_fix_ssrc(NULL, (char *)buf, len, 1, session->media.video_ssrc, session->media.video_ssrc_peer);
1266
                                                /* Forward the message to the peer */
1267
                                                send(session->media.video_rtcp_fd, sbuf, protected, 0);
1268
                                        }
1269
                                } else {
1270
                                        /* Fix SSRCs as the gateway does */
1271
                                        JANUS_LOG(LOG_HUGE, "[SIP] Fixing SSRCs (local %u, peer %u)\n",
1272
                                                session->media.video_ssrc, session->media.video_ssrc_peer);
1273
                                        janus_rtcp_fix_ssrc(NULL, (char *)buf, len, 1, session->media.video_ssrc, session->media.video_ssrc_peer);
1274
                                        /* Forward the message to the peer */
1275
                                        send(session->media.video_rtcp_fd, buf, len, 0);
1276
                                }
1277
                        }
1278
                } else {
1279
                        if(session->media.has_audio && session->media.audio_rtcp_fd) {
1280
                                /* Is SRTP involved? */
1281
                                if(session->media.has_srtp_local) {
1282
                                        char sbuf[2048];
1283
                                        memcpy(&sbuf, buf, len);
1284
                                        int protected = len;
1285
                                        int res = srtp_protect_rtcp(session->media.audio_srtp_out, &sbuf, &protected);
1286
                                        if(res != err_status_ok) {
1287
                                                JANUS_LOG(LOG_ERR, "[SIP-%s] Audio SRTCP protect error... %s (len=%d-->%d)...\n",
1288
                                                        session->account.username, janus_sip_get_srtp_error(res), len, protected);
1289
                                        } else {
1290
                                                /* Fix SSRCs as the gateway does */
1291
                                                JANUS_LOG(LOG_HUGE, "[SIP] Fixing SSRCs (local %u, peer %u)\n",
1292
                                                        session->media.audio_ssrc, session->media.audio_ssrc_peer);
1293
                                                janus_rtcp_fix_ssrc(NULL, (char *)buf, len, 1, session->media.audio_ssrc, session->media.audio_ssrc_peer);
1294
                                                /* Forward the message to the peer */
1295
                                                send(session->media.audio_rtcp_fd, sbuf, protected, 0);
1296
                                        }
1297
                                } else {
1298
                                        /* Fix SSRCs as the gateway does */
1299
                                        JANUS_LOG(LOG_HUGE, "[SIP] Fixing SSRCs (local %u, peer %u)\n",
1300
                                                session->media.audio_ssrc, session->media.audio_ssrc_peer);
1301
                                        janus_rtcp_fix_ssrc(NULL, (char *)buf, len, 1, session->media.audio_ssrc, session->media.audio_ssrc_peer);
1302
                                        /* Forward the message to the peer */
1303
                                        send(session->media.audio_rtcp_fd, buf, len, 0);
1304
                                }
1305
                        }
1306
                }
1307
        }
1308
}
1309

    
1310
void janus_sip_hangup_media(janus_plugin_session *handle) {
1311
        JANUS_LOG(LOG_INFO, "No WebRTC media anymore\n");
1312
        if(g_atomic_int_get(&stopping) || !g_atomic_int_get(&initialized))
1313
                return;
1314
        janus_sip_session *session = (janus_sip_session *)handle->plugin_handle;
1315
        if(!session) {
1316
                JANUS_LOG(LOG_ERR, "No session associated with this handle...\n");
1317
                return;
1318
        }
1319
        if(session->destroyed)
1320
                return;
1321
        if(g_atomic_int_add(&session->hangingup, 1))
1322
                return;
1323
        if(!(session->status == janus_sip_call_status_inviting ||
1324
                 session->status == janus_sip_call_status_invited ||
1325
                 session->status == janus_sip_call_status_incall))
1326
                return;
1327
        /* Get rid of the recorders, if available */
1328
        janus_mutex_lock(&session->rec_mutex);
1329
        if(session->arc) {
1330
                janus_recorder_close(session->arc);
1331
                JANUS_LOG(LOG_INFO, "Closed user's audio recording %s\n", session->arc->filename ? session->arc->filename : "??");
1332
                janus_recorder_free(session->arc);
1333
        }
1334
        session->arc = NULL;
1335
        if(session->arc_peer) {
1336
                janus_recorder_close(session->arc_peer);
1337
                JANUS_LOG(LOG_INFO, "Closed peer's audio recording %s\n", session->arc_peer->filename ? session->arc_peer->filename : "??");
1338
                janus_recorder_free(session->arc_peer);
1339
        }
1340
        session->arc_peer = NULL;
1341
        if(session->vrc) {
1342
                janus_recorder_close(session->vrc);
1343
                JANUS_LOG(LOG_INFO, "Closed user's video recording %s\n", session->vrc->filename ? session->vrc->filename : "??");
1344
                janus_recorder_free(session->vrc);
1345
        }
1346
        session->vrc = NULL;
1347
        if(session->vrc_peer) {
1348
                janus_recorder_close(session->vrc_peer);
1349
                JANUS_LOG(LOG_INFO, "Closed peer's video recording %s\n", session->vrc_peer->filename ? session->vrc_peer->filename : "??");
1350
                janus_recorder_free(session->vrc_peer);
1351
        }
1352
        session->vrc_peer = NULL;
1353
        janus_mutex_unlock(&session->rec_mutex);
1354
        /* FIXME Simulate a "hangup" coming from the browser */
1355
        janus_sip_message *msg = g_malloc0(sizeof(janus_sip_message));
1356
        msg->handle = handle;
1357
        msg->message = g_strdup("{\"request\":\"hangup\"}");
1358
        msg->transaction = NULL;
1359
        msg->sdp_type = NULL;
1360
        msg->sdp = NULL;
1361
        g_async_queue_push(messages, msg);
1362
}
1363

    
1364
/* Thread to handle incoming messages */
1365
static void *janus_sip_handler(void *data) {
1366
        JANUS_LOG(LOG_VERB, "Joining SIP handler thread\n");
1367
        janus_sip_message *msg = NULL;
1368
        int error_code = 0;
1369
        char error_cause[512];
1370
        json_t *root = NULL;
1371
        while(g_atomic_int_get(&initialized) && !g_atomic_int_get(&stopping)) {
1372
                msg = g_async_queue_pop(messages);
1373
                if(msg == NULL)
1374
                        continue;
1375
                if(msg == &exit_message)
1376
                        break;
1377
                if(msg->handle == NULL) {
1378
                        janus_sip_message_free(msg);
1379
                        continue;
1380
                }
1381
                janus_sip_session *session = NULL;
1382
                janus_mutex_lock(&sessions_mutex);
1383
                if(g_hash_table_lookup(sessions, msg->handle) != NULL ) {
1384
                        session = (janus_sip_session *)msg->handle->plugin_handle;
1385
                }
1386
                janus_mutex_unlock(&sessions_mutex);
1387
                if(!session) {
1388
                        JANUS_LOG(LOG_ERR, "No session associated with this handle...\n");
1389
                        janus_sip_message_free(msg);
1390
                        continue;
1391
                }
1392
                if(session->destroyed) {
1393
                        janus_sip_message_free(msg);
1394
                        continue;
1395
                }
1396
                /* Handle request */
1397
                error_code = 0;
1398
                root = NULL;
1399
                JANUS_LOG(LOG_VERB, "Handling message: %s\n", msg->message);
1400
                if(msg->message == NULL) {
1401
                        JANUS_LOG(LOG_ERR, "No message??\n");
1402
                        error_code = JANUS_SIP_ERROR_NO_MESSAGE;
1403
                        g_snprintf(error_cause, 512, "%s", "No message??");
1404
                        goto error;
1405
                }
1406
                json_error_t error;
1407
                root = json_loads(msg->message, 0, &error);
1408
                if(!root) {
1409
                        JANUS_LOG(LOG_ERR, "JSON error: on line %d: %s\n", error.line, error.text);
1410
                        error_code = JANUS_SIP_ERROR_INVALID_JSON;
1411
                        g_snprintf(error_cause, 512, "JSON error: on line %d: %s", error.line, error.text);
1412
                        goto error;
1413
                }
1414
                if(!json_is_object(root)) {
1415
                        JANUS_LOG(LOG_ERR, "JSON error: not an object\n");
1416
                        error_code = JANUS_SIP_ERROR_INVALID_JSON;
1417
                        g_snprintf(error_cause, 512, "JSON error: not an object");
1418
                        goto error;
1419
                }
1420
                JANUS_VALIDATE_JSON_OBJECT(root, request_parameters,
1421
                        error_code, error_cause, TRUE,
1422
                        JANUS_SIP_ERROR_MISSING_ELEMENT, JANUS_SIP_ERROR_INVALID_ELEMENT);
1423
                if(error_code != 0)
1424
                        goto error;
1425
                json_t *request = json_object_get(root, "request");
1426
                const char *request_text = json_string_value(request);
1427
                json_t *result = NULL;
1428
                char *sdp_type = NULL, *sdp = NULL;
1429

    
1430
                if(!strcasecmp(request_text, "register")) {
1431
                        /* Send a REGISTER */
1432
                        if(session->account.registration_status > janus_sip_registration_status_unregistered) {
1433
                                JANUS_LOG(LOG_ERR, "Already registered (%s)\n", session->account.username);
1434
                                error_code = JANUS_SIP_ERROR_ALREADY_REGISTERED;
1435
                                g_snprintf(error_cause, 512, "Already registered (%s)", session->account.username);
1436
                                goto error;
1437
                        }
1438

    
1439
                        /* Cleanup old values */
1440
                        if(session->account.identity != NULL) {
1441
                                g_hash_table_remove(identities, session->account.identity);
1442
                                g_free(session->account.identity);
1443
                        }
1444
                        session->account.identity = NULL;
1445
                        session->account.sips = TRUE;
1446
                        if(session->account.username != NULL)
1447
                                g_free(session->account.username);
1448
                        session->account.username = NULL;
1449
                        if(session->account.display_name != NULL)
1450
                                g_free(session->account.display_name);
1451
                        session->account.display_name = NULL;
1452
                        if(session->account.authuser != NULL)
1453
                                g_free(session->account.authuser);
1454
                        session->account.authuser = NULL;
1455
                        if(session->account.secret != NULL)
1456
                                g_free(session->account.secret);
1457
                        session->account.secret = NULL;
1458
                        session->account.secret_type = janus_sip_secret_type_unknown;
1459
                        if(session->account.proxy != NULL)
1460
                                g_free(session->account.proxy);
1461
                        session->account.proxy = NULL;
1462
                        if(session->account.user_agent != NULL)
1463
                                g_free(session->account.user_agent);
1464
                        session->account.user_agent = NULL;
1465
                        session->account.registration_status = janus_sip_registration_status_unregistered;
1466

    
1467
                        gboolean guest = FALSE;
1468
                        JANUS_VALIDATE_JSON_OBJECT(root, register_parameters,
1469
                                error_code, error_cause, TRUE,
1470
                                JANUS_SIP_ERROR_MISSING_ELEMENT, JANUS_SIP_ERROR_INVALID_ELEMENT);
1471
                        if(error_code != 0)
1472
                                goto error;
1473
                        json_t *type = json_object_get(root, "type");
1474
                        if(type != NULL) {
1475
                                const char *type_text = json_string_value(type);
1476
                                if(!strcmp(type_text, "guest")) {
1477
                                        JANUS_LOG(LOG_INFO, "Registering as a guest\n");
1478
                                        guest = TRUE;
1479
                                } else {
1480
                                        JANUS_LOG(LOG_WARN, "Unknown type '%s', ignoring...\n", type_text);
1481
                                }
1482
                        }
1483

    
1484
                        gboolean send_register = TRUE;
1485
                        json_t *do_register = json_object_get(root, "send_register");
1486
                        if(do_register != NULL) {
1487
                                if(guest) {
1488
                                        JANUS_LOG(LOG_ERR, "Conflicting elements: send_register cannot be true if guest is true\n");
1489
                                        error_code = JANUS_SIP_ERROR_INVALID_ELEMENT;
1490
                                        g_snprintf(error_cause, 512, "Conflicting elements: send_register cannot be true if guest is true");
1491
                                        goto error;
1492
                                }
1493
                                send_register = json_is_true(do_register);
1494
                        }
1495

    
1496
                        gboolean sips = TRUE;
1497
                        json_t *do_sips = json_object_get(root, "sips");
1498
                        if(do_sips != NULL) {
1499
                                sips = json_is_true(do_sips);
1500
                        }
1501

    
1502
                        /* Parse address */
1503
                        json_t *proxy = json_object_get(root, "proxy");
1504
                        const char *proxy_text = NULL;
1505

    
1506
                        if (proxy && !json_is_null(proxy)) {
1507
                                /* Has to be validated separately because it could be null */
1508
                                JANUS_VALIDATE_JSON_OBJECT(root, proxy_parameters,
1509
                                        error_code, error_cause, TRUE,
1510
                                        JANUS_SIP_ERROR_MISSING_ELEMENT, JANUS_SIP_ERROR_INVALID_ELEMENT);
1511
                                if(error_code != 0)
1512
                                        goto error;
1513
                                proxy_text = json_string_value(proxy);
1514
                                janus_sip_uri_t proxy_uri;
1515
                                if (janus_sip_parse_proxy_uri(&proxy_uri, proxy_text) < 0) {
1516
                                        JANUS_LOG(LOG_ERR, "Invalid proxy address %s\n", proxy_text);
1517
                                        error_code = JANUS_SIP_ERROR_INVALID_ADDRESS;
1518
                                        g_snprintf(error_cause, 512, "Invalid proxy address %s\n", proxy_text);
1519
                                        goto error;
1520
                                }
1521
                        }
1522

    
1523
                        /* Parse register TTL */
1524
                        int ttl = register_ttl;
1525
                        json_t *reg_ttl = json_object_get(root, "register_ttl");
1526
                        if (reg_ttl && json_is_integer(reg_ttl))
1527
                                ttl = json_integer_value(reg_ttl);
1528
                        if (ttl <= 0)
1529
                                ttl = JANUS_DEFAULT_REGISTER_TTL;
1530

    
1531
                        /* Parse display name */
1532
                        const char* display_name_text = NULL;
1533
                        json_t *display_name = json_object_get(root, "display_name");
1534
                        if (display_name && json_is_string(display_name))
1535
                                display_name_text = json_string_value(display_name);
1536

    
1537
                        /* Parse user agent */
1538
                        const char* user_agent_text = NULL;
1539
                        json_t *user_agent = json_object_get(root, "user_agent");
1540
                        if (user_agent && json_is_string(user_agent))
1541
                                user_agent_text = json_string_value(user_agent);
1542

    
1543
                        /* Now the user part, if needed */
1544
                        json_t *username = json_object_get(root, "username");
1545
                        if(!guest && !username) {
1546
                                /* The username is mandatory if we're not registering as guests */
1547
                                JANUS_LOG(LOG_ERR, "Missing element (username)\n");
1548
                                error_code = JANUS_SIP_ERROR_MISSING_ELEMENT;
1549
                                g_snprintf(error_cause, 512, "Missing element (username)");
1550
                                goto error;
1551
                        }
1552
                        const char *username_text = NULL;
1553
                        janus_sip_uri_t username_uri;
1554
                        char user_id[256];
1555
                        if(username) {
1556
                                /* Parse address */
1557
                                username_text = json_string_value(username);
1558
                                if (janus_sip_parse_uri(&username_uri, username_text) < 0) {
1559
                                        JANUS_LOG(LOG_ERR, "Invalid user address %s\n", username_text);
1560
                                        error_code = JANUS_SIP_ERROR_INVALID_ADDRESS;
1561
                                        g_snprintf(error_cause, 512, "Invalid user address %s\n", username_text);
1562
                                        goto error;
1563
                                }
1564
                                g_strlcpy(user_id, username_uri.url->url_user, sizeof(user_id));
1565
                        }
1566
                        if(guest) {
1567
                                /* Not needed, we can stop here: just pick a random username if it wasn't provided and say we're registered */
1568
                                if(!username)
1569
                                        g_snprintf(user_id, 255, "janus-sip-%"SCNu32"", janus_random_uint32());
1570
                                JANUS_LOG(LOG_INFO, "Guest will have username %s\n", user_id);
1571
                                send_register = FALSE;
1572
                        } else {
1573
                                json_t *secret = json_object_get(root, "secret");
1574
                                json_t *ha1_secret = json_object_get(root, "ha1_secret");
1575
                                json_t *authuser = json_object_get(root, "authuser");
1576
                                if(!secret && !ha1_secret) {
1577
                                        JANUS_LOG(LOG_ERR, "Missing element (secret or ha1_secret)\n");
1578
                                        error_code = JANUS_SIP_ERROR_MISSING_ELEMENT;
1579
                                        g_snprintf(error_cause, 512, "Missing element (secret or ha1_secret)");
1580
                                        goto error;
1581
                                }
1582
                                if(secret && ha1_secret) {
1583
                                        JANUS_LOG(LOG_ERR, "Conflicting elements specified (secret and ha1_secret)\n");
1584
                                        error_code = JANUS_SIP_ERROR_INVALID_ELEMENT;
1585
                                        g_snprintf(error_cause, 512, "Conflicting elements specified (secret and ha1_secret)");
1586
                                        goto error;
1587
                                }
1588
                                const char *secret_text;
1589
                                if(secret) {
1590
                                        secret_text = json_string_value(secret);
1591
                                        session->account.secret = g_strdup(secret_text);
1592
                                        session->account.secret_type = janus_sip_secret_type_plaintext;
1593
                                } else {
1594
                                        secret_text = json_string_value(ha1_secret);
1595
                                        session->account.secret = g_strdup(secret_text);
1596
                                        session->account.secret_type = janus_sip_secret_type_hashed;
1597
                                }
1598
                                if (authuser) {
1599
                                        const char *authuser_text;
1600
                                        authuser_text = json_string_value(authuser);
1601
                                        session->account.authuser = g_strdup(authuser_text);
1602
                                } else {
1603
                                        session->account.authuser = g_strdup(user_id);
1604
                                }
1605
                                /* Got the values, try registering now */
1606
                                JANUS_LOG(LOG_VERB, "Registering user %s (secret %s) @ %s through %s\n",
1607
                                        username_text, secret_text, username_uri.url->url_host, proxy_text != NULL ? proxy_text : "(null)");
1608
                        }
1609

    
1610
                        session->account.identity = g_strdup(username_text);
1611
                        g_hash_table_insert(identities, session->account.identity, session);
1612
                        session->account.sips = sips;
1613
                        session->account.username = g_strdup(user_id);
1614
                        if (display_name_text) {
1615
                                session->account.display_name = g_strdup(display_name_text);
1616
                        }
1617
                        if (user_agent_text) {
1618
                                session->account.user_agent = g_strdup(user_agent_text);
1619
                        }
1620
                        if (proxy_text) {
1621
                                session->account.proxy = g_strdup(proxy_text);
1622
                        }
1623

    
1624
                        session->account.registration_status = janus_sip_registration_status_registering;
1625
                        if(session->stack == NULL) {
1626
                                /* Start the thread first */
1627
                                GError *error = NULL;
1628
                                g_thread_try_new("worker", janus_sip_sofia_thread, session, &error);
1629
                                if(error != NULL) {
1630
                                        JANUS_LOG(LOG_ERR, "Got error %d (%s) trying to launch the SIP Sofia thread...\n", error->code, error->message ? error->message : "??");
1631
                                        error_code = JANUS_SIP_ERROR_UNKNOWN_ERROR;
1632
                                        g_snprintf(error_cause, 512, "Got error %d (%s) trying to launch the SIP Sofia thread", error->code, error->message ? error->message : "??");
1633
                                        goto error;
1634
                                }
1635
                                long int timeout = 0;
1636
                                while(session->stack == NULL || session->stack->s_nua == NULL) {
1637
                                        g_usleep(100000);
1638
                                        timeout += 100000;
1639
                                        if(timeout >= 2000000) {
1640
                                                break;
1641
                                        }
1642
                                }
1643
                                if(timeout >= 2000000) {
1644
                                        JANUS_LOG(LOG_ERR, "Two seconds passed and still no NUA, problems with the thread?\n");
1645
                                        error_code = JANUS_SIP_ERROR_UNKNOWN_ERROR;
1646
                                        g_snprintf(error_cause, 512, "Two seconds passed and still no NUA, problems with the thread?");
1647
                                        goto error;
1648
                                }
1649
                        }
1650
                        if(session->stack->s_nh_r != NULL) {
1651
                                nua_handle_destroy(session->stack->s_nh_r);
1652
                                session->stack->s_nh_r = NULL;
1653
                        }
1654

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

    
2317
                        char payload[64];
2318
                        g_snprintf(payload, sizeof(payload), "Signal=%s\r\nDuration=%d", digit_text, duration_ms);
2319
                        nua_info(session->stack->s_nh_i,
2320
                                SIPTAG_CONTENT_TYPE_STR("application/dtmf-relay"),
2321
                                SIPTAG_PAYLOAD_STR(payload),
2322
                                TAG_END());
2323
                } else {
2324
                        JANUS_LOG(LOG_ERR, "Unknown request (%s)\n", request_text);
2325
                        error_code = JANUS_SIP_ERROR_INVALID_REQUEST;
2326
                        g_snprintf(error_cause, 512, "Unknown request (%s)", request_text);
2327
                        goto error;
2328
                }
2329

    
2330
                json_decref(root);
2331
                /* Prepare JSON event */
2332
                json_t *event = json_object();
2333
                json_object_set_new(event, "sip", json_string("event"));
2334
                if(result != NULL)
2335
                        json_object_set_new(event, "result", result);
2336
                char *event_text = json_dumps(event, JSON_INDENT(3) | JSON_PRESERVE_ORDER);
2337
                json_decref(event);
2338
                JANUS_LOG(LOG_VERB, "Pushing event: %s\n", event_text);
2339
                int ret = gateway->push_event(msg->handle, &janus_sip_plugin, msg->transaction, event_text, sdp_type, sdp);
2340
                JANUS_LOG(LOG_VERB, "  >> %d (%s)\n", ret, janus_get_api_error(ret));
2341
                g_free(event_text);
2342
                if(sdp)
2343
                        g_free(sdp);
2344
                janus_sip_message_free(msg);
2345
                continue;
2346

    
2347
error:
2348
                {
2349
                        if(root != NULL)
2350
                                json_decref(root);
2351
                        /* Prepare JSON error event */
2352
                        json_t *event = json_object();
2353
                        json_object_set_new(event, "sip", json_string("event"));
2354
                        json_object_set_new(event, "error_code", json_integer(error_code));
2355
                        json_object_set_new(event, "error", json_string(error_cause));
2356
                        char *event_text = json_dumps(event, JSON_INDENT(3) | JSON_PRESERVE_ORDER);
2357
                        json_decref(event);
2358
                        JANUS_LOG(LOG_VERB, "Pushing event: %s\n", event_text);
2359
                        int ret = gateway->push_event(msg->handle, &janus_sip_plugin, msg->transaction, event_text, NULL, NULL);
2360
                        JANUS_LOG(LOG_VERB, "  >> %d (%s)\n", ret, janus_get_api_error(ret));
2361
                        g_free(event_text);
2362
                        janus_sip_message_free(msg);
2363
                }
2364
        }
2365
        JANUS_LOG(LOG_VERB, "Leaving SIP handler thread\n");
2366
        return NULL;
2367
}
2368

    
2369

    
2370
/* Sofia callbacks */
2371
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[])
2372
{
2373
        janus_sip_session *session = (janus_sip_session *)magic;
2374
        ssip_t *ssip = session->stack;
2375

    
2376
        /* Notify event handlers about the content of the whole incoming SIP message, if any */
2377
        if(gateway->events_is_enabled() && ssip) {
2378
                /* Print the incoming message */
2379
                size_t msg_size = 0;
2380
                msg_t* msg = nua_current_request(nua);
2381
                if(msg) {
2382
                        char *msg_str = msg_as_string(ssip->s_home, msg, NULL, 0, &msg_size);
2383
                        json_t *info = json_object();
2384
                        json_object_set_new(info, "event", json_string("sip-in"));
2385
                        json_object_set_new(info, "sip", json_string(msg_str));
2386
                        gateway->notify_event(session->handle, info);
2387
                }
2388
        }
2389

    
2390
        switch (event) {
2391
        /* Status or Error Indications */
2392
                case nua_i_active:
2393
                        JANUS_LOG(LOG_VERB, "[%s][%s]: %d %s\n", session->account.username, nua_event_name(event), status, phrase ? phrase : "??");
2394
                        break;
2395
                case nua_i_error:
2396
                        JANUS_LOG(LOG_VERB, "[%s][%s]: %d %s\n", session->account.username, nua_event_name(event), status, phrase ? phrase : "??");
2397
                        break;
2398
                case nua_i_fork:
2399
                        JANUS_LOG(LOG_VERB, "[%s][%s]: %d %s\n", session->account.username, nua_event_name(event), status, phrase ? phrase : "??");
2400
                        break;
2401
                case nua_i_media_error:
2402
                        JANUS_LOG(LOG_VERB, "[%s][%s]: %d %s\n", session->account.username, nua_event_name(event), status, phrase ? phrase : "??");
2403
                        break;
2404
                case nua_i_subscription:
2405
                        JANUS_LOG(LOG_VERB, "[%s][%s]: %d %s\n", session->account.username, nua_event_name(event), status, phrase ? phrase : "??");
2406
                        break;
2407
                case nua_i_state:
2408
                        JANUS_LOG(LOG_VERB, "[%s][%s]: %d %s\n", session->account.username, nua_event_name(event), status, phrase ? phrase : "??");
2409
                        tagi_t const *ti = tl_find(tags, nutag_callstate);
2410
                        enum nua_callstate callstate = ti ? ti->t_value : -1;
2411
                        /* There are several call states, but we care about the terminated state in order to send the 'hangup' event
2412
                         * and the proceeding state in order to send the 'proceeding' event so the client can play a ringback tone for
2413
                         * the user since we don't send early media. (assuming this is the right session, of course).
2414
                         * http://sofia-sip.sourceforge.net/refdocs/nua/nua__tag_8h.html#a516dc237722dc8ca4f4aa3524b2b444b
2415
                         */
2416
                        if (callstate == nua_callstate_proceeding &&
2417
                                    (session->stack->s_nh_i == nh || session->stack->s_nh_i == NULL)) {
2418
                                json_t *call = json_object();
2419
                                json_object_set_new(call, "sip", json_string("event"));
2420
                                json_t *calling = json_object();
2421
                                json_object_set_new(calling, "event", json_string("proceeding"));
2422
                                json_object_set_new(calling, "code", json_integer(status));
2423
                                json_object_set_new(call, "result", calling);
2424
                                char *call_text = json_dumps(call, JSON_INDENT(3) | JSON_PRESERVE_ORDER);
2425
                                json_decref(call);
2426
                                JANUS_LOG(LOG_VERB, "Pushing event: %s\n", call_text);
2427
                                int ret = gateway->push_event(session->handle, &janus_sip_plugin, session->transaction, call_text, NULL, NULL);
2428
                                JANUS_LOG(LOG_VERB, "  >> %d (%s)\n", ret, janus_get_api_error(ret));
2429
                                g_free(call_text);
2430
                                /* Also notify event handlers */
2431
                                if(notify_events && gateway->events_is_enabled()) {
2432
                                        json_t *info = json_object();
2433
                                        json_object_set_new(info, "event", json_string("proceeding"));
2434
                                        if(session->callid)
2435
                                                json_object_set_new(info, "call-id", json_string(session->callid));
2436
                                        json_object_set_new(info, "code", json_integer(status));
2437
                                        gateway->notify_event(session->handle, info);
2438
                                }
2439
                        } else if(callstate == nua_callstate_terminated &&
2440
                                        (session->stack->s_nh_i == nh || session->stack->s_nh_i == NULL)) {
2441
                                session->status = janus_sip_call_status_idle;
2442
                                session->stack->s_nh_i = NULL;
2443
                                json_t *call = json_object();
2444
                                json_object_set_new(call, "sip", json_string("event"));
2445
                                json_t *calling = json_object();
2446
                                json_object_set_new(calling, "event", json_string("hangup"));
2447
                                json_object_set_new(calling, "code", json_integer(status));
2448
                                json_object_set_new(calling, "reason", json_string(phrase ? phrase : ""));
2449
                                json_object_set_new(call, "result", calling);
2450
                                char *call_text = json_dumps(call, JSON_INDENT(3) | JSON_PRESERVE_ORDER);
2451
                                json_decref(call);
2452
                                JANUS_LOG(LOG_VERB, "Pushing event: %s\n", call_text);
2453
                                int ret = gateway->push_event(session->handle, &janus_sip_plugin, session->transaction, call_text, NULL, NULL);
2454
                                JANUS_LOG(LOG_VERB, "  >> %d (%s)\n", ret, janus_get_api_error(ret));
2455
                                g_free(call_text);
2456
                                /* Also notify event handlers */
2457
                                if(notify_events && gateway->events_is_enabled()) {
2458
                                        json_t *info = json_object();
2459
                                        json_object_set_new(info, "event", json_string("hangup"));
2460
                                        if(session->callid)
2461
                                                json_object_set_new(info, "call-id", json_string(session->callid));
2462
                                        json_object_set_new(info, "code", json_integer(status));
2463
                                        if(phrase)
2464
                                                json_object_set_new(info, "reason", json_string(phrase));
2465
                                        gateway->notify_event(session->handle, info);
2466
                                }
2467
                                /* Get rid of any PeerConnection that may have been set up */
2468
                                if(session->callid)
2469
                                        g_hash_table_remove(callids, session->callid);
2470
                                g_free(session->callid);
2471
                                session->callid = NULL;
2472
                                g_free(session->transaction);
2473
                                session->transaction = NULL;
2474
                                gateway->close_pc(session->handle);
2475
                        }
2476
                        break;
2477
                case nua_i_terminated:
2478
                        JANUS_LOG(LOG_VERB, "[%s][%s]: %d %s\n", session->account.username, nua_event_name(event), status, phrase ? phrase : "??");
2479
                        break;
2480
        /* SIP requests */
2481
                case nua_i_ack:
2482
                        JANUS_LOG(LOG_VERB, "[%s][%s]: %d %s\n", session->account.username, nua_event_name(event), status, phrase ? phrase : "??");
2483
                        break;
2484
                case nua_i_outbound:
2485
                        JANUS_LOG(LOG_VERB, "[%s][%s]: %d %s\n", session->account.username, nua_event_name(event), status, phrase ? phrase : "??");
2486
                        break;
2487
                case nua_i_bye: {
2488
                        JANUS_LOG(LOG_VERB, "[%s][%s]: %d %s\n", session->account.username, nua_event_name(event), status, phrase ? phrase : "??");
2489
                        break;
2490
                }
2491
                case nua_i_cancel: {
2492
                        JANUS_LOG(LOG_VERB, "[%s][%s]: %d %s\n", session->account.username, nua_event_name(event), status, phrase ? phrase : "??");
2493
                        break;
2494
                }
2495
                case nua_i_invite: {
2496
                        JANUS_LOG(LOG_VERB, "[%s][%s]: %d %s\n", session->account.username, nua_event_name(event), status, phrase ? phrase : "??");
2497
                        if(ssip == NULL) {
2498
                                JANUS_LOG(LOG_ERR, "\tInvalid SIP stack\n");
2499
                                nua_respond(nh, 500, sip_status_phrase(500), TAG_END());
2500
                                break;
2501
                        }
2502
                        sdp_parser_t *parser = sdp_parse(ssip->s_home, sip->sip_payload->pl_data, sip->sip_payload->pl_len, 0);
2503
                        if(!sdp_session(parser)) {
2504
                                JANUS_LOG(LOG_ERR, "\tError parsing SDP!\n");
2505
                                nua_respond(nh, 488, sip_status_phrase(488), TAG_END());
2506
                                sdp_parser_free(parser);
2507
                                break;
2508
                        }
2509
                        if(session->stack->s_nh_i != NULL) {
2510
                                if(session->stack->s_nh_i == nh) {
2511
                                        /* re-INVITE, we don't support those. */
2512
                                        nua_respond(nh, 488, sip_status_phrase(488), TAG_END());
2513
                                } else if(session->status >= janus_sip_call_status_inviting) {
2514
                                        /* Busy with another call */
2515
                                        JANUS_LOG(LOG_VERB, "\tAlready in a call (busy, status=%s)\n", janus_sip_call_status_string(session->status));
2516
                                        nua_respond(nh, 486, sip_status_phrase(486), TAG_END());
2517
                                        /* Notify the web app about the missed invite */
2518
                                        json_t *missed = json_object();
2519
                                        json_object_set_new(missed, "sip", json_string("event"));
2520
                                        json_t *result = json_object();
2521
                                        json_object_set_new(result, "event", json_string("missed_call"));
2522
                                        char *caller_text = url_as_string(session->stack->s_home, sip->sip_from->a_url);
2523
                                        json_object_set_new(result, "caller", json_string(caller_text));
2524
                                        su_free(session->stack->s_home, caller_text);
2525
                                        if (sip->sip_from && sip->sip_from->a_display) {
2526
                                                json_object_set_new(result, "displayname", json_string(sip->sip_from->a_display));
2527
                                        }
2528
                                        json_object_set_new(missed, "result", result);
2529
                                        char *missed_text = json_dumps(missed, JSON_INDENT(3) | JSON_PRESERVE_ORDER);
2530
                                        json_decref(missed);
2531
                                        JANUS_LOG(LOG_VERB, "Pushing event to peer: %s\n", missed_text);
2532
                                        int ret = gateway->push_event(session->handle, &janus_sip_plugin, session->transaction, missed_text, NULL, NULL);
2533
                                        JANUS_LOG(LOG_VERB, "  >> %d (%s)\n", ret, janus_get_api_error(ret));
2534
                                        g_free(missed_text);
2535
                                        /* Also notify event handlers */
2536
                                        if(notify_events && gateway->events_is_enabled()) {
2537
                                                json_t *info = json_object();
2538
                                                json_object_set_new(info, "event", json_string("missed_call"));
2539
                                                json_object_set_new(info, "caller", json_string(caller_text));
2540
                                                gateway->notify_event(session->handle, info);
2541
                                        }
2542
                                }
2543
                                sdp_parser_free(parser);
2544
                                break;
2545
                        }
2546
                        /* New incoming call */
2547
                        session->callee = g_strdup(url_as_string(session->stack->s_home, sip->sip_from->a_url));
2548
                        session->callid = sip && sip->sip_call_id ? g_strdup(sip->sip_call_id->i_id) : NULL;
2549
                        if(session->callid)
2550
                                g_hash_table_insert(callids, session->callid, session);
2551
                        session->status = janus_sip_call_status_invited;
2552
                        /* Clean up SRTP stuff from before first, in case it's still needed */
2553
                        janus_sip_srtp_cleanup(session);
2554
                        /* Parse SDP */
2555
                        char *fixed_sdp = g_strdup(sip->sip_payload->pl_data);
2556
                        JANUS_LOG(LOG_VERB, "Someone is inviting us in a call:\n%s", sip->sip_payload->pl_data);
2557
                        sdp_session_t *sdp = sdp_session(parser);
2558
                        janus_sip_sdp_process(session, sdp, FALSE);
2559
                        /* Send SDP to the browser */
2560
                        json_t *call = json_object();
2561
                        json_object_set_new(call, "sip", json_string("event"));
2562
                        json_t *calling = json_object();
2563
                        json_object_set_new(calling, "event", json_string("incomingcall"));
2564
                        json_object_set_new(calling, "username", json_string(session->callee));
2565
                        if(sip->sip_from && sip->sip_from->a_display) {
2566
                                json_object_set_new(calling, "displayname", json_string(sip->sip_from->a_display));
2567
                        }
2568
                        if(session->media.has_srtp_remote) {
2569
                                /* FIXME Maybe a true/false instead? */
2570
                                json_object_set_new(calling, "srtp", json_string(session->media.require_srtp ? "sdes_mandatory" : "sdes_optional"));
2571
                        }
2572
                        json_object_set_new(call, "result", calling);
2573
                        char *call_text = json_dumps(call, JSON_INDENT(3) | JSON_PRESERVE_ORDER);
2574
                        json_decref(call);
2575
                        JANUS_LOG(LOG_VERB, "Pushing event to peer: %s\n", call_text);
2576
                        int ret = gateway->push_event(session->handle, &janus_sip_plugin, session->transaction, call_text, "offer", fixed_sdp);
2577
                        JANUS_LOG(LOG_VERB, "  >> %d (%s)\n", ret, janus_get_api_error(ret));
2578
                        g_free(call_text);
2579
                        /* Also notify event handlers */
2580
                        if(notify_events && gateway->events_is_enabled()) {
2581
                                json_t *info = json_object();
2582
                                json_object_set_new(info, "event", json_string("incomingcall"));
2583
                                if(session->callid)
2584
                                        json_object_set_new(info, "call-id", json_string(session->callid));
2585
                                json_object_set_new(info, "username", json_string(session->callee));
2586
                                if(sip->sip_from && sip->sip_from->a_display)
2587
                                        json_object_set_new(info, "displayname", json_string(sip->sip_from->a_display));
2588
                                gateway->notify_event(session->handle, info);
2589
                        }
2590
                        g_free(fixed_sdp);
2591
                        sdp_parser_free(parser);
2592
                        /* Send a Ringing back */
2593
                        nua_respond(nh, 180, sip_status_phrase(180), TAG_END());
2594
                        session->stack->s_nh_i = nh;
2595
                        break;
2596
                }
2597
                case nua_i_options:
2598
                        JANUS_LOG(LOG_VERB, "[%s][%s]: %d %s\n", session->account.username, nua_event_name(event), status, phrase ? phrase : "??");
2599
                        /* FIXME Should we handle this message? for now we reply with a 405 Method Not Implemented */
2600
                        nua_respond(nh, 405, sip_status_phrase(405), TAG_END());
2601
                        break;
2602
        /* Responses */
2603
                case nua_r_get_params:
2604
                        JANUS_LOG(LOG_VERB, "[%s][%s]: %d %s\n", session->account.username, nua_event_name(event), status, phrase ? phrase : "??");
2605
                        break;
2606
                case nua_r_set_params:
2607
                        JANUS_LOG(LOG_VERB, "[%s][%s]: %d %s\n", session->account.username, nua_event_name(event), status, phrase ? phrase : "??");
2608
                        break;
2609
                case nua_r_notifier:
2610
                        JANUS_LOG(LOG_VERB, "[%s][%s]: %d %s\n", session->account.username, nua_event_name(event), status, phrase ? phrase : "??");
2611
                        break;
2612
                case nua_r_shutdown:
2613
                        JANUS_LOG(LOG_VERB, "[%s][%s]: %d %s\n", session->account.username, nua_event_name(event), status, phrase ? phrase : "??");
2614
                        if(status < 200 && !g_atomic_int_get(&stopping)) {
2615
                                /* shutdown in progress -> return */
2616
                                break;
2617
                        }
2618
                        if(ssip != NULL) {
2619
                                /* end the event loop. su_root_run() will return */
2620
                                su_root_break(ssip->s_root);
2621
                        }
2622
                        break;
2623
                case nua_r_terminate:
2624
                        JANUS_LOG(LOG_VERB, "[%s][%s]: %d %s\n", session->account.username, nua_event_name(event), status, phrase ? phrase : "??");
2625
                        break;
2626
        /* SIP responses */
2627
                case nua_r_bye:
2628
                        JANUS_LOG(LOG_VERB, "[%s][%s]: %d %s\n", session->account.username, nua_event_name(event), status, phrase ? phrase : "??");
2629
                        break;
2630
                case nua_r_cancel:
2631
                        JANUS_LOG(LOG_VERB, "[%s][%s]: %d %s\n", session->account.username, nua_event_name(event), status, phrase ? phrase : "??");
2632
                        break;
2633
                case nua_r_info:
2634
                        JANUS_LOG(LOG_VERB, "[%s][%s]: %d %s\n", session->account.username, nua_event_name(event), status, phrase ? phrase : "??");
2635
                        break;
2636
                case nua_r_invite: {
2637
                        JANUS_LOG(LOG_VERB, "[%s][%s]: %d %s\n", session->account.username, nua_event_name(event), status, phrase ? phrase : "??");
2638

    
2639
                        if(status < 200) {
2640
                                /* Not ready yet (FIXME May this be pranswer?? we don't handle it yet...) */
2641
                                break;
2642
                        } else if(status == 401 || status == 407) {
2643
                                char auth[256];
2644
                                const char* scheme;
2645
                                const char* realm;
2646
                                if(status == 401) {
2647
                                         /* Get scheme/realm from 401 error */
2648
                                        sip_www_authenticate_t const* www_auth = sip->sip_www_authenticate;
2649
                                        scheme = www_auth->au_scheme;
2650
                                        realm = msg_params_find(www_auth->au_params, "realm=");
2651
                                } else {
2652
                                         /* Get scheme/realm from 407 error, proxy-auth */
2653
                                        sip_proxy_authenticate_t const* proxy_auth = sip->sip_proxy_authenticate;
2654
                                        scheme = proxy_auth->au_scheme;
2655
                                        realm = msg_params_find(proxy_auth->au_params, "realm=");
2656
                                }
2657
                                memset(auth, 0, sizeof(auth));
2658
                                g_snprintf(auth, sizeof(auth), "%s%s:%s:%s:%s%s",
2659
                                        session->account.secret_type == janus_sip_secret_type_hashed ? "HA1+" : "",
2660
                                        scheme,
2661
                                        realm,
2662
                                        session->account.authuser ? session->account.authuser : "null",
2663
                                        session->account.secret_type == janus_sip_secret_type_hashed ? "HA1+" : "",
2664
                                        session->account.secret ? session->account.secret : "null");
2665
                                JANUS_LOG(LOG_VERB, "\t%s\n", auth);
2666
                                /* Authenticate */
2667
                                nua_authenticate(nh,
2668
                                        NUTAG_AUTH(auth),
2669
                                        TAG_END());
2670
                                break;
2671
                        } else if(status >= 400) {
2672
                                break;
2673
                        }
2674
                        if(ssip == NULL) {
2675
                                JANUS_LOG(LOG_ERR, "\tInvalid SIP stack\n");
2676
                                nua_respond(nh, 500, sip_status_phrase(500), TAG_END());
2677
                                break;
2678
                        }
2679
                        sdp_parser_t *parser = sdp_parse(ssip->s_home, sip->sip_payload->pl_data, sip->sip_payload->pl_len, 0);
2680
                        if(!sdp_session(parser)) {
2681
                                JANUS_LOG(LOG_ERR, "\tError parsing SDP!\n");
2682
                                nua_respond(nh, 488, sip_status_phrase(488), TAG_END());
2683
                                sdp_parser_free(parser);
2684
                                break;
2685
                        }
2686
                        /* Send an ACK, if needed */
2687
                        if(!session->media.autoack) {
2688
                                char *route = sip->sip_record_route ? url_as_string(session->stack->s_home, sip->sip_record_route->r_url) : NULL;
2689
                                JANUS_LOG(LOG_INFO, "Sending ACK (route=%s)\n", route ? route : "none");
2690
                                nua_ack(nh,
2691
                                        TAG_IF(route, NTATAG_DEFAULT_PROXY(route)),
2692
                                        TAG_END());
2693
                        }
2694
                        /* Parse SDP */
2695
                        JANUS_LOG(LOG_VERB, "Peer accepted our call:\n%s", sip->sip_payload->pl_data);
2696
                        session->status = janus_sip_call_status_incall;
2697
                        char *fixed_sdp = g_strdup(sip->sip_payload->pl_data);
2698
                        sdp_session_t *sdp = sdp_session(parser);
2699
                        janus_sip_sdp_process(session, sdp, TRUE);
2700
                        /* If we asked for SRTP and are not getting it, fail */
2701
                        if(session->media.require_srtp && !session->media.has_srtp_remote) {
2702
                                JANUS_LOG(LOG_ERR, "\tWe asked for mandatory SRTP but didn't get any in the reply!\n");
2703
                                sdp_parser_free(parser);
2704
                                g_free(fixed_sdp);
2705
                                /* Hangup immediately */
2706
                                session->status = janus_sip_call_status_closing;
2707
                                nua_bye(nh, TAG_END());
2708
                                g_free(session->callee);
2709
                                session->callee = NULL;
2710
                                break;
2711
                        }
2712
                        if(session->media.audio_pt > -1) {
2713
                                session->media.audio_pt_name = janus_get_codec_from_pt(fixed_sdp, session->media.audio_pt);
2714
                                JANUS_LOG(LOG_VERB, "Detected audio codec: %d (%s)\n", session->media.audio_pt, session->media.audio_pt_name);
2715
                        }
2716
                        if(session->media.video_pt > -1) {
2717
                                session->media.video_pt_name = janus_get_codec_from_pt(fixed_sdp, session->media.video_pt);
2718
                                JANUS_LOG(LOG_VERB, "Detected video codec: %d (%s)\n", session->media.video_pt, session->media.video_pt_name);
2719
                        }
2720
                        session->media.ready = 1;        /* FIXME Maybe we need a better way to signal this */
2721
                        GError *error = NULL;
2722
                        g_thread_try_new("janus rtp handler", janus_sip_relay_thread, session, &error);
2723
                        if(error != NULL) {
2724
                                JANUS_LOG(LOG_ERR, "Got error %d (%s) trying to launch the RTP/RTCP thread...\n", error->code, error->message ? error->message : "??");
2725
                        }
2726
                        /* Send SDP to the browser */
2727
                        json_t *call = json_object();
2728
                        json_object_set_new(call, "sip", json_string("event"));
2729
                        json_t *calling = json_object();
2730
                        json_object_set_new(calling, "event", json_string("accepted"));
2731
                        json_object_set_new(calling, "username", json_string(session->callee));
2732
                        json_object_set_new(call, "result", calling);
2733
                        char *call_text = json_dumps(call, JSON_INDENT(3) | JSON_PRESERVE_ORDER);
2734
                        json_decref(call);
2735
                        JANUS_LOG(LOG_VERB, "Pushing event to peer: %s\n", call_text);
2736
                        int ret = gateway->push_event(session->handle, &janus_sip_plugin, session->transaction, call_text, "answer", fixed_sdp);
2737
                        JANUS_LOG(LOG_VERB, "  >> %d (%s)\n", ret, janus_get_api_error(ret));
2738
                        g_free(call_text);
2739
                        /* Also notify event handlers */
2740
                        if(notify_events && gateway->events_is_enabled()) {
2741
                                json_t *info = json_object();
2742
                                json_object_set_new(info, "event", json_string("accepted"));
2743
                                if(session->callid)
2744
                                        json_object_set_new(info, "call-id", json_string(session->callid));
2745
                                json_object_set_new(info, "username", json_string(session->callee));
2746
                                gateway->notify_event(session->handle, info);
2747
                        }
2748
                        g_free(fixed_sdp);
2749
                        sdp_parser_free(parser);
2750
                        break;
2751
                }
2752
                case nua_r_register: {
2753
                        JANUS_LOG(LOG_VERB, "[%s][%s]: %d %s\n", session->account.username, nua_event_name(event), status, phrase ? phrase : "??");
2754
                        if(status == 200) {
2755
                                if(session->account.registration_status < janus_sip_registration_status_registered)
2756
                                        session->account.registration_status = janus_sip_registration_status_registered;
2757
                                JANUS_LOG(LOG_VERB, "Successfully registered\n");
2758
                                /* Notify the browser */
2759
                                json_t *call = json_object();
2760
                                json_object_set_new(call, "sip", json_string("event"));
2761
                                json_t *calling = json_object();
2762
                                json_object_set_new(calling, "event", json_string("registered"));
2763
                                json_object_set_new(calling, "username", json_string(session->account.username));
2764
                                json_object_set_new(calling, "register_sent", json_string("true"));
2765
                                json_object_set_new(call, "result", calling);
2766
                                char *call_text = json_dumps(call, JSON_INDENT(3) | JSON_PRESERVE_ORDER);
2767
                                json_decref(call);
2768
                                JANUS_LOG(LOG_VERB, "Pushing event: %s\n", call_text);
2769
                                int ret = gateway->push_event(session->handle, &janus_sip_plugin, session->transaction, call_text, NULL, NULL);
2770
                                JANUS_LOG(LOG_VERB, "  >> %d (%s)\n", ret, janus_get_api_error(ret));
2771
                                g_free(call_text);
2772
                                /* Also notify event handlers */
2773
                                if(notify_events && gateway->events_is_enabled()) {
2774
                                        json_t *info = json_object();
2775
                                        json_object_set_new(info, "event", json_string("registered"));
2776
                                        json_object_set_new(info, "identity", json_string(session->account.identity));
2777
                                        if(session->account.proxy)
2778
                                                json_object_set_new(info, "proxy", json_string(session->account.proxy));
2779
                                        gateway->notify_event(session->handle, info);
2780
                                }
2781
                        } else if(status == 401) {
2782
                                /* Get scheme/realm from 401 error */
2783
                                sip_www_authenticate_t const* www_auth = sip->sip_www_authenticate;
2784
                                char const* scheme = www_auth->au_scheme;
2785
                                const char* realm = msg_params_find(www_auth->au_params, "realm=");
2786
                                char auth[256];
2787
                                memset(auth, 0, sizeof(auth));
2788
                                g_snprintf(auth, sizeof(auth), "%s%s:%s:%s:%s%s",
2789
                                        session->account.secret_type == janus_sip_secret_type_hashed ? "HA1+" : "",
2790
                                        scheme,
2791
                                        realm,
2792
                                        session->account.authuser ? session->account.authuser : "null",
2793
                                        session->account.secret_type == janus_sip_secret_type_hashed ? "HA1+" : "",
2794
                                        session->account.secret);
2795
                                JANUS_LOG(LOG_VERB, "\t%s\n", auth);
2796
                                /* Authenticate */
2797
                                nua_authenticate(nh,
2798
                                        NUTAG_AUTH(auth),
2799
                                        TAG_END());
2800
                        } else if(status >= 400) {
2801
                                /* Authentication failed? */
2802
                                session->account.registration_status = janus_sip_registration_status_failed;
2803
                                /* Tell the browser... */
2804
                                json_t *event = json_object();
2805
                                json_object_set_new(event, "sip", json_string("event"));
2806
                                json_t *result = json_object();
2807
                                json_object_set_new(result, "event", json_string("registration_failed"));
2808
                                json_object_set_new(result, "code", json_integer(status));
2809
                                json_object_set_new(result, "reason", json_string(phrase ? phrase : ""));
2810
                                json_object_set_new(event, "result", result);
2811
                                char *event_text = json_dumps(event, JSON_INDENT(3) | JSON_PRESERVE_ORDER);
2812
                                json_decref(event);
2813
                                JANUS_LOG(LOG_VERB, "Pushing event: %s\n", event_text);
2814
                                int ret = gateway->push_event(session->handle, &janus_sip_plugin, session->transaction, event_text, NULL, NULL);
2815
                                JANUS_LOG(LOG_VERB, "  >> %d (%s)\n", ret, janus_get_api_error(ret));
2816
                                g_free(event_text);
2817
                                /* Also notify event handlers */
2818
                                if(notify_events && gateway->events_is_enabled()) {
2819
                                        json_t *info = json_object();
2820
                                        json_object_set_new(info, "event", json_string("registration_failed"));
2821
                                        json_object_set_new(info, "code", json_integer(status));
2822
                                        if(phrase)
2823
                                                json_object_set_new(info, "reason", json_string(phrase ? phrase : ""));
2824
                                        gateway->notify_event(session->handle, info);
2825
                                }
2826
                        }
2827
                        break;
2828
                }
2829
                default:
2830
                        /* unknown event -> print out error message */
2831
                        JANUS_LOG(LOG_ERR, "Unknown event %d (%s)\n", event, nua_event_name(event));
2832
                        break;
2833
        }
2834
}
2835

    
2836
void janus_sip_sdp_process(janus_sip_session *session, sdp_session_t *sdp, gboolean answer) {
2837
        if(!session || !sdp)
2838
                return;
2839
        /* c= */
2840
        if(sdp->sdp_connection && sdp->sdp_connection->c_address) {
2841
                g_free(session->media.remote_ip);
2842
                session->media.remote_ip = g_strdup(sdp->sdp_connection->c_address);
2843
                JANUS_LOG(LOG_VERB, "  >> Media connection:\n");
2844
                JANUS_LOG(LOG_VERB, "       %s\n", session->media.remote_ip);
2845
        }
2846
        JANUS_LOG(LOG_VERB, "  >> Media lines:\n");
2847
        sdp_media_t *m = sdp->sdp_media;
2848
        while(m) {
2849
                session->media.require_srtp = session->media.require_srtp || (m->m_proto_name && !strcasecmp(m->m_proto_name, "RTP/SAVP"));
2850
                if(m->m_type == sdp_media_audio) {
2851
                        JANUS_LOG(LOG_VERB, "       Audio: %lu\n", m->m_port);
2852
                        if(m->m_port) {
2853
                                session->media.has_audio = 1;
2854
                                session->media.remote_audio_rtp_port = m->m_port;
2855
                                session->media.remote_audio_rtcp_port = m->m_port+1;        /* FIXME We're assuming RTCP is on the next port */
2856
                        }
2857
                } else if(m->m_type == sdp_media_video) {
2858
                        JANUS_LOG(LOG_VERB, "       Video: %lu\n", m->m_port);
2859
                        if(m->m_port) {
2860
                                session->media.has_video = 1;
2861
                                session->media.remote_video_rtp_port = m->m_port;
2862
                                session->media.remote_video_rtcp_port = m->m_port+1;        /* FIXME We're assuming RTCP is on the next port */
2863
                        }
2864
                } else {
2865
                        JANUS_LOG(LOG_WARN, "       Unsupported media line (not audio/video)\n");
2866
                        m = m->m_next;
2867
                        continue;
2868
                }
2869
                JANUS_LOG(LOG_VERB, "       Media connections:\n");
2870
                if(m->m_connections) {
2871
                        sdp_connection_t *c = m->m_connections;
2872
                        while(c) {
2873
                                if(c->c_address) {
2874
                                        g_free(session->media.remote_ip);
2875
                                        session->media.remote_ip = g_strdup(c->c_address);
2876
                                        JANUS_LOG(LOG_VERB, "         [%s]\n", session->media.remote_ip);
2877
                                }
2878
                                c = c->c_next;
2879
                        }
2880
                }
2881
                JANUS_LOG(LOG_VERB, "       Media RTP maps:\n");
2882
                sdp_rtpmap_t *r = m->m_rtpmaps;
2883
                while(r) {
2884
                        JANUS_LOG(LOG_VERB, "         [%u] %s\n", r->rm_pt, r->rm_encoding);
2885
                        r = r->rm_next;
2886
                }
2887
                JANUS_LOG(LOG_VERB, "       Media attributes:\n");
2888
                sdp_attribute_t *a = m->m_attributes;
2889
                while(a) {
2890
                        if(a->a_name) {
2891
                                if(!strcasecmp(a->a_name, "rtpmap")) {
2892
                                        JANUS_LOG(LOG_VERB, "         RTP Map:     %s\n", a->a_value);
2893
                                } else if(!strcasecmp(a->a_name, "crypto")) {
2894
                                        JANUS_LOG(LOG_VERB, "         Crypto:      %s\n", a->a_value);
2895
                                        if(m->m_type == sdp_media_audio || m->m_type == sdp_media_video) {
2896
                                                gint32 tag = 0;
2897
                                                int suite;
2898
                                                char crypto[40];
2899
                                                /* FIXME inline can be more complex than that, and we're currently only offering SHA1_80 */
2900
                                                int res = sscanf(a->a_value, "%"SCNi32" AES_CM_128_HMAC_SHA1_%2d inline:%40s",
2901
                                                        &tag, &suite, crypto);
2902
                                                if(res != 3) {
2903
                                                        JANUS_LOG(LOG_WARN, "Failed to parse crypto line, ignoring... %s\n", a->a_value);
2904
                                                } else {
2905
                                                        gboolean video = (m->m_type == sdp_media_video);
2906
                                                        int current_suite = video ? session->media.video_srtp_suite_in : session->media.audio_srtp_suite_in;
2907
                                                        if(current_suite == 0) {
2908
                                                                if(video)
2909
                                                                        session->media.video_srtp_suite_in = suite;
2910
                                                                else
2911
                                                                        session->media.audio_srtp_suite_in = suite;
2912
                                                                janus_sip_srtp_set_remote(session, video, crypto, suite);
2913
                                                                session->media.has_srtp_remote = TRUE;
2914
                                                        } else {
2915
                                                                JANUS_LOG(LOG_WARN, "We already configured a %s crypto context (AES_CM_128_HMAC_SHA1_%d), skipping additional crypto line\n",
2916
                                                                        video ? "video" : "audio", current_suite);
2917
                                                        }
2918
                                                }
2919
                                        }
2920
                                }
2921
                        }
2922
                        a = a->a_next;
2923
                }
2924
                if(answer && (m->m_type == sdp_media_audio || m->m_type == sdp_media_video)) {
2925
                        /* Check which codec was negotiated eventually */
2926
                        int pt = -1;
2927
                        if(!m->m_rtpmaps) {
2928
                                JANUS_LOG(LOG_VERB, "No RTP maps?? trying formats...\n");
2929
                                if(m->m_format) {
2930
                                        sdp_list_t *fmt = m->m_format;
2931
                                        pt = atoi(fmt->l_text);
2932
                                }
2933
                        } else {
2934
                                sdp_rtpmap_t *r = m->m_rtpmaps;
2935
                                pt = r->rm_pt;
2936
                        }
2937
                        if(pt > -1) {
2938
                                if(m->m_type == sdp_media_audio) {
2939
                                        session->media.audio_pt = pt;
2940
                                } else {
2941
                                        session->media.video_pt = pt;
2942
                                }
2943
                        }
2944
                }
2945
                m = m->m_next;
2946
        }
2947
}
2948

    
2949
char *janus_sip_sdp_manipulate(janus_sip_session *session, sdp_session_t *sdp, gboolean answer) {
2950
        if(!session || !session->stack || !sdp)
2951
                return NULL;
2952
        /* Placeholders for later */
2953
        sdp_attribute_t crypto_audio = {
2954
                .a_size = sizeof(sdp_attribute_t),
2955
                .a_name = "crypto",
2956
                .a_value = "audio"
2957
        };
2958
        sdp_attribute_t crypto_video = {
2959
                .a_size = sizeof(sdp_attribute_t),
2960
                .a_name = "crypto",
2961
                .a_value = "video"
2962
        };
2963
        /* Start replacing stuff */
2964
        if(sdp->sdp_connection && sdp->sdp_connection->c_address) {
2965
                sdp->sdp_connection->c_address = local_ip;
2966
        }
2967
        JANUS_LOG(LOG_VERB, "Setting protocol to %s\n", session->media.require_srtp ? "RTP/SAVP" : "RTP/AVP");
2968
        sdp_media_t *m = sdp->sdp_media;
2969
        while(m) {
2970
                m->m_proto = session->media.require_srtp ? sdp_proto_srtp : sdp_proto_rtp;
2971
                m->m_proto_name = session->media.require_srtp ? "RTP/SAVP" : "RTP/AVP";
2972
                if(m->m_type == sdp_media_audio) {
2973
                        m->m_port = session->media.local_audio_rtp_port;
2974
                        if(session->media.has_srtp_local) {
2975
                                sdp_attribute_append(&m->m_attributes, &crypto_audio);
2976
                        }
2977
                } else if(m->m_type == sdp_media_video) {
2978
                        m->m_port = session->media.local_video_rtp_port;
2979
                        if(session->media.has_srtp_local) {
2980
                                sdp_attribute_append(&m->m_attributes, &crypto_video);
2981
                        }
2982
                }
2983
                if(m->m_connections) {
2984
                        sdp_connection_t *c = m->m_connections;
2985
                        while(c) {
2986
                                c->c_address = local_ip;
2987
                                c = c->c_next;
2988
                        }
2989
                }
2990
                if(answer && (m->m_type == sdp_media_audio || m->m_type == sdp_media_video)) {
2991
                        /* Check which codec was negotiated eventually */
2992
                        int pt = -1;
2993
                        if(!m->m_rtpmaps) {
2994
                                JANUS_LOG(LOG_VERB, "No RTP maps?? trying formats...\n");
2995
                                if(m->m_format) {
2996
                                        sdp_list_t *fmt = m->m_format;
2997
                                        pt = atoi(fmt->l_text);
2998
                                }
2999
                        } else {
3000
                                sdp_rtpmap_t *r = m->m_rtpmaps;
3001
                                pt = r->rm_pt;
3002
                        }
3003
                        if(pt > -1) {
3004
                                if(m->m_type == sdp_media_audio) {
3005
                                        session->media.audio_pt = pt;
3006
                                } else {
3007
                                        session->media.video_pt = pt;
3008
                                }
3009
                        }
3010
                }
3011
                m = m->m_next;
3012
        }
3013
        /* Generate a SDP string out of our changes */
3014
        char buf[2048];
3015
        sdp_printer_t *printer = sdp_print(session->stack->s_home, sdp, buf, 2048, 0);
3016
        if(!sdp_message(printer)) {
3017
                sdp_printer_free(printer);
3018
                return NULL;
3019
        }
3020
        sdp_printer_free(printer);
3021
        char *new_sdp = g_strdup(buf);
3022
        /* If any crypto placeholer was there, fix that */
3023
        if(session->media.has_srtp_local) {
3024
                if(session->media.has_audio) {
3025
                        char *crypto = NULL;
3026
                        session->media.audio_srtp_suite_out = 80;
3027
                        janus_sip_srtp_set_local(session, FALSE, &crypto);
3028
                        /* FIXME 32? 80? Both? */
3029
                        char cryptoline[100];
3030
                        g_snprintf(cryptoline, 100, "a=crypto:1 AES_CM_128_HMAC_SHA1_80 inline:%s", crypto);
3031
                        g_free(crypto);
3032
                        new_sdp = janus_string_replace(new_sdp, "a=crypto:audio", cryptoline);
3033
                }
3034
                if(session->media.has_video) {
3035
                        char *crypto = NULL;
3036
                        session->media.video_srtp_suite_out = 80;
3037
                        janus_sip_srtp_set_local(session, TRUE, &crypto);
3038
                        /* FIXME 32? 80? Both? */
3039
                        char cryptoline[100];
3040
                        g_snprintf(cryptoline, 100, "a=crypto:1 AES_CM_128_HMAC_SHA1_80 inline:%s", crypto);
3041
                        g_free(crypto);
3042
                        new_sdp = janus_string_replace(new_sdp, "a=crypto:video", cryptoline);
3043
                }
3044
        }
3045
        return new_sdp;
3046
}
3047

    
3048
/* Bind local RTP/RTCP sockets */
3049
static int janus_sip_allocate_local_ports(janus_sip_session *session) {
3050
        if(session == NULL) {
3051
                JANUS_LOG(LOG_ERR, "Invalid session\n");
3052
                return -1;
3053
        }
3054
        /* Reset status */
3055
        if(session->media.audio_rtp_fd != -1) {
3056
                close(session->media.audio_rtp_fd);
3057
                session->media.audio_rtp_fd = -1;
3058
        }
3059
        if(session->media.audio_rtcp_fd != -1) {
3060
                close(session->media.audio_rtcp_fd);
3061
                session->media.audio_rtcp_fd = -1;
3062
        }
3063
        session->media.local_audio_rtp_port = 0;
3064
        session->media.local_audio_rtcp_port = 0;
3065
        session->media.audio_ssrc = 0;
3066
        if(session->media.video_rtp_fd != -1) {
3067
                close(session->media.video_rtp_fd);
3068
                session->media.video_rtp_fd = -1;
3069
        }
3070
        if(session->media.video_rtcp_fd != -1) {
3071
                close(session->media.video_rtcp_fd);
3072
                session->media.video_rtcp_fd = -1;
3073
        }
3074
        session->media.local_video_rtp_port = 0;
3075
        session->media.local_video_rtcp_port = 0;
3076
        session->media.video_ssrc = 0;
3077
        /* Start */
3078
        int attempts = 100;        /* FIXME Don't retry forever */
3079
        if(session->media.has_audio) {
3080
                JANUS_LOG(LOG_VERB, "Allocating audio ports:\n");
3081
                struct sockaddr_in audio_rtp_address, audio_rtcp_address;
3082
                while(session->media.local_audio_rtp_port == 0 || session->media.local_audio_rtcp_port == 0) {
3083
                        if(attempts == 0)        /* Too many failures */
3084
                                return -1;
3085
                        if(session->media.audio_rtp_fd == -1) {
3086
                                session->media.audio_rtp_fd = socket(AF_INET, SOCK_DGRAM, 0);
3087
                        }
3088
                        if(session->media.audio_rtcp_fd == -1) {
3089
                                session->media.audio_rtcp_fd = socket(AF_INET, SOCK_DGRAM, 0);
3090
                        }
3091
                        int rtp_port = g_random_int_range(10000, 60000);        /* FIXME Should this be configurable? */
3092
                        if(rtp_port % 2)
3093
                                rtp_port++;        /* Pick an even port for RTP */
3094
                        audio_rtp_address.sin_family = AF_INET;
3095
                        audio_rtp_address.sin_port = htons(rtp_port);
3096
                        inet_pton(AF_INET, local_ip, &audio_rtp_address.sin_addr.s_addr);
3097
                        if(bind(session->media.audio_rtp_fd, (struct sockaddr *)(&audio_rtp_address), sizeof(struct sockaddr)) < 0) {
3098
                                JANUS_LOG(LOG_ERR, "Bind failed for audio RTP (port %d), trying a different one...\n", rtp_port);
3099
                                attempts--;
3100
                                continue;
3101
                        }
3102
                        JANUS_LOG(LOG_VERB, "Audio RTP listener bound to port %d\n", rtp_port);
3103
                        int rtcp_port = rtp_port+1;
3104
                        audio_rtcp_address.sin_family = AF_INET;
3105
                        audio_rtcp_address.sin_port = htons(rtcp_port);
3106
                        inet_pton(AF_INET, local_ip, &audio_rtcp_address.sin_addr.s_addr);
3107
                        if(bind(session->media.audio_rtcp_fd, (struct sockaddr *)(&audio_rtcp_address), sizeof(struct sockaddr)) < 0) {
3108
                                JANUS_LOG(LOG_ERR, "Bind failed for audio RTCP (port %d), trying a different one...\n", rtcp_port);
3109
                                /* RTP socket is not valid anymore, reset it */
3110
                                close(session->media.audio_rtp_fd);
3111
                                session->media.audio_rtp_fd = -1;
3112
                                attempts--;
3113
                                continue;
3114
                        }
3115
                        JANUS_LOG(LOG_VERB, "Audio RTCP listener bound to port %d\n", rtcp_port);
3116
                        session->media.local_audio_rtp_port = rtp_port;
3117
                        session->media.local_audio_rtcp_port = rtcp_port;
3118
                }
3119
        }
3120
        if(session->media.has_video) {
3121
                JANUS_LOG(LOG_VERB, "Allocating video ports:\n");
3122
                struct sockaddr_in video_rtp_address, video_rtcp_address;
3123
                while(session->media.local_video_rtp_port == 0 || session->media.local_video_rtcp_port == 0) {
3124
                        if(attempts == 0)        /* Too many failures */
3125
                                return -1;
3126
                        if(session->media.video_rtp_fd == -1) {
3127
                                session->media.video_rtp_fd = socket(AF_INET, SOCK_DGRAM, 0);
3128
                        }
3129
                        if(session->media.video_rtcp_fd == -1) {
3130
                                session->media.video_rtcp_fd = socket(AF_INET, SOCK_DGRAM, 0);
3131
                        }
3132
                        int rtp_port = g_random_int_range(10000, 60000);        /* FIXME Should this be configurable? */
3133
                        if(rtp_port % 2)
3134
                                rtp_port++;        /* Pick an even port for RTP */
3135
                        video_rtp_address.sin_family = AF_INET;
3136
                        video_rtp_address.sin_port = htons(rtp_port);
3137
                        inet_pton(AF_INET, local_ip, &video_rtp_address.sin_addr.s_addr);
3138
                        if(bind(session->media.video_rtp_fd, (struct sockaddr *)(&video_rtp_address), sizeof(struct sockaddr)) < 0) {
3139
                                JANUS_LOG(LOG_ERR, "Bind failed for video RTP (port %d), trying a different one...\n", rtp_port);
3140
                                attempts--;
3141
                                continue;
3142
                        }
3143
                        JANUS_LOG(LOG_VERB, "Video RTP listener bound to port %d\n", rtp_port);
3144
                        int rtcp_port = rtp_port+1;
3145
                        video_rtcp_address.sin_family = AF_INET;
3146
                        video_rtcp_address.sin_port = htons(rtcp_port);
3147
                        inet_pton(AF_INET, local_ip, &video_rtcp_address.sin_addr.s_addr);
3148
                        if(bind(session->media.video_rtcp_fd, (struct sockaddr *)(&video_rtcp_address), sizeof(struct sockaddr)) < 0) {
3149
                                JANUS_LOG(LOG_ERR, "Bind failed for video RTCP (port %d), trying a different one...\n", rtcp_port);
3150
                                /* RTP socket is not valid anymore, reset it */
3151
                                close(session->media.video_rtp_fd);
3152
                                session->media.video_rtp_fd = -1;
3153
                                attempts--;
3154
                                continue;
3155
                        }
3156
                        JANUS_LOG(LOG_VERB, "Video RTCP listener bound to port %d\n", rtcp_port);
3157
                        session->media.local_video_rtp_port = rtp_port;
3158
                        session->media.local_video_rtcp_port = rtcp_port;
3159
                }
3160
        }
3161
        return 0;
3162
}
3163

    
3164
/* Thread to relay RTP/RTCP frames coming from the SIP peer */
3165
static void *janus_sip_relay_thread(void *data) {
3166
        janus_sip_session *session = (janus_sip_session *)data;
3167
        if(!session || !session->account.username || !session->callee) {
3168
                g_thread_unref(g_thread_self());
3169
                return NULL;
3170
        }
3171
        JANUS_LOG(LOG_VERB, "Starting relay thread (%s <--> %s)\n", session->account.username, session->callee);
3172

    
3173
        gboolean have_server_ip = TRUE;
3174
        struct sockaddr_in server_addr;
3175
        memset(&server_addr, 0, sizeof(server_addr));
3176
        server_addr.sin_family = AF_INET;
3177
        if((inet_aton(session->media.remote_ip, &server_addr.sin_addr)) <= 0) {        /* Not a numeric IP... */
3178
                struct hostent *host = gethostbyname(session->media.remote_ip);        /* ...resolve name */
3179
                if(!host) {
3180
                        JANUS_LOG(LOG_ERR, "[SIP-%s] Couldn't get host (%s)\n", session->account.username, session->media.remote_ip);
3181
                        have_server_ip = FALSE;
3182
                } else {
3183
                        server_addr.sin_addr = *(struct in_addr *)host->h_addr_list;
3184
                }
3185
        }
3186

    
3187
        /* Connect peers (FIXME This pretty much sucks right now) */
3188
        if(have_server_ip && session->media.remote_audio_rtp_port) {
3189
                server_addr.sin_port = htons(session->media.remote_audio_rtp_port);
3190
                if(connect(session->media.audio_rtp_fd, (struct sockaddr *)&server_addr, sizeof(struct sockaddr)) == -1) {
3191
                        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);
3192
                        JANUS_LOG(LOG_ERR, "[SIP-%s]   -- %d (%s)\n", session->account.username, errno, strerror(errno));
3193
                }
3194
        }
3195
        if(have_server_ip && session->media.remote_audio_rtcp_port) {
3196
                server_addr.sin_port = htons(session->media.remote_audio_rtcp_port);
3197
                if(connect(session->media.audio_rtcp_fd, (struct sockaddr *)&server_addr, sizeof(struct sockaddr)) == -1) {
3198
                        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);
3199
                        JANUS_LOG(LOG_ERR, "[SIP-%s]   -- %d (%s)\n", session->account.username, errno, strerror(errno));
3200
                }
3201
        }
3202
        if(have_server_ip && session->media.remote_video_rtp_port) {
3203
                server_addr.sin_port = htons(session->media.remote_video_rtp_port);
3204
                if(connect(session->media.video_rtp_fd, (struct sockaddr *)&server_addr, sizeof(struct sockaddr)) == -1) {
3205
                        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);
3206
                        JANUS_LOG(LOG_ERR, "[SIP-%s]   -- %d (%s)\n", session->account.username, errno, strerror(errno));
3207
                }
3208
        }
3209
        if(have_server_ip && session->media.remote_video_rtcp_port) {
3210
                server_addr.sin_port = htons(session->media.remote_video_rtcp_port);
3211
                if(connect(session->media.video_rtcp_fd, (struct sockaddr *)&server_addr, sizeof(struct sockaddr)) == -1) {
3212
                        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);
3213
                        JANUS_LOG(LOG_ERR, "[SIP-%s]   -- %d (%s)\n", session->account.username, errno, strerror(errno));
3214
                }
3215
        }
3216

    
3217
        if(!session->callee) {
3218
                JANUS_LOG(LOG_VERB, "[SIP-%s] Leaving thread, no callee...\n", session->account.username);
3219
                g_thread_unref(g_thread_self());
3220
                return NULL;
3221
        }
3222
        /* File descriptors */
3223
        socklen_t addrlen;
3224
        struct sockaddr_in remote;
3225
        int resfd = 0, bytes = 0;
3226
        struct pollfd fds[4];
3227
        char buffer[1500];
3228
        memset(buffer, 0, 1500);
3229
        /* Loop */
3230
        int num = 0;
3231
        gboolean goon = TRUE;
3232
        while(goon && session != NULL && !session->destroyed &&
3233
                        session->status > janus_sip_call_status_idle &&
3234
                        session->status < janus_sip_call_status_closing) {        /* FIXME We need a per-call watchdog as well */
3235
                /* Prepare poll */
3236
                num = 0;
3237
                if(session->media.audio_rtp_fd != -1) {
3238
                        fds[num].fd = session->media.audio_rtp_fd;
3239
                        fds[num].events = POLLIN;
3240
                        fds[num].revents = 0;
3241
                        num++;
3242
                }
3243
                if(session->media.audio_rtcp_fd != -1) {
3244
                        fds[num].fd = session->media.audio_rtcp_fd;
3245
                        fds[num].events = POLLIN;
3246
                        fds[num].revents = 0;
3247
                        num++;
3248
                }
3249
                if(session->media.video_rtp_fd != -1) {
3250
                        fds[num].fd = session->media.video_rtp_fd;
3251
                        fds[num].events = POLLIN;
3252
                        fds[num].revents = 0;
3253
                        num++;
3254
                }
3255
                if(session->media.video_rtcp_fd != -1) {
3256
                        fds[num].fd = session->media.video_rtcp_fd;
3257
                        fds[num].events = POLLIN;
3258
                        fds[num].revents = 0;
3259
                        num++;
3260
                }
3261
                /* Wait for some data */
3262
                resfd = poll(fds, num, 1000);
3263
                if(resfd < 0) {
3264
                        JANUS_LOG(LOG_ERR, "[SIP-%s] Error polling...\n", session->account.username);
3265
                        JANUS_LOG(LOG_ERR, "[SIP-%s]   -- %d (%s)\n", session->account.username, errno, strerror(errno));
3266
                        break;
3267
                } else if(resfd == 0) {
3268
                        /* No data, keep going */
3269
                        continue;
3270
                }
3271
                if(session == NULL || session->destroyed ||
3272
                                session->status <= janus_sip_call_status_idle ||
3273
                                session->status >= janus_sip_call_status_closing)
3274
                        break;
3275
                int i = 0;
3276
                for(i=0; i<num; i++) {
3277
                        if(fds[i].revents & (POLLERR | POLLHUP)) {
3278
                                /* Socket error? */
3279
                                JANUS_LOG(LOG_ERR, "[SIP-%s] Error polling: %s...\n", session->account.username,
3280
                                        fds[i].revents & POLLERR ? "POLLERR" : "POLLHUP");
3281
                                JANUS_LOG(LOG_ERR, "[SIP-%s]   -- %d (%s)\n", session->account.username, errno, strerror(errno));
3282
                                goon = FALSE;        /* Can we assume it's pretty much over, after a POLLERR? */
3283
                                /* FIXME Simulate a "hangup" coming from the browser */
3284
                                janus_sip_message *msg = g_malloc0(sizeof(janus_sip_message));
3285
                                msg->handle = session->handle;
3286
                                msg->message = g_strdup("{\"request\":\"hangup\"}");
3287
                                msg->transaction = NULL;
3288
                                msg->sdp_type = NULL;
3289
                                msg->sdp = NULL;
3290
                                g_async_queue_push(messages, msg);
3291
                                break;
3292
                        } else if(fds[i].revents & POLLIN) {
3293
                                /* Got an RTP/RTCP packet */
3294
                                if(session->media.audio_rtp_fd != -1 && fds[i].fd == session->media.audio_rtp_fd) {
3295
                                        /* Got something audio (RTP) */
3296
                                        addrlen = sizeof(remote);
3297
                                        bytes = recvfrom(session->media.audio_rtp_fd, buffer, 1500, 0, (struct sockaddr*)&remote, &addrlen);
3298
                                        //~ JANUS_LOG(LOG_VERB, "************************\nGot %d bytes on the audio RTP channel...\n", bytes);
3299
                                        //~ rtp_header_t *rtp = (rtp_header_t *)buffer;
3300
                                        //~ JANUS_LOG(LOG_VERB, " ... parsed RTP packet (ssrc=%u, pt=%u, seq=%u, ts=%u)...\n",
3301
                                                //~ ntohl(rtp->ssrc), rtp->type, ntohs(rtp->seq_number), ntohl(rtp->timestamp));
3302
                                        if(session->media.audio_ssrc_peer == 0) {
3303
                                                rtp_header *header = (rtp_header *)buffer;
3304
                                                session->media.audio_ssrc_peer = ntohl(header->ssrc);
3305
                                                JANUS_LOG(LOG_VERB, "Got SIP peer audio SSRC: %"SCNu32"\n", session->media.audio_ssrc_peer);
3306
                                        }
3307
                                        /* Is this SRTP? */
3308
                                        if(session->media.has_srtp_remote) {
3309
                                                int buflen = bytes;
3310
                                                err_status_t res = srtp_unprotect(session->media.audio_srtp_in, buffer, &buflen);
3311
                                                if(res != err_status_ok && res != err_status_replay_fail && res != err_status_replay_old) {
3312
                                                        rtp_header *header = (rtp_header *)buffer;
3313
                                                        guint32 timestamp = ntohl(header->timestamp);
3314
                                                        guint16 seq = ntohs(header->seq_number);
3315
                                                        JANUS_LOG(LOG_ERR, "[SIP-%s] Audio SRTP unprotect error: %s (len=%d-->%d, ts=%"SCNu32", seq=%"SCNu16")\n",
3316
                                                                session->account.username, janus_sip_get_srtp_error(res), bytes, buflen, timestamp, seq);
3317
                                                        continue;
3318
                                                }
3319
                                                bytes = buflen;
3320
                                        }
3321
                                        /* Save the frame if we're recording */
3322
                                        janus_recorder_save_frame(session->arc_peer, buffer, bytes);
3323
                                        /* Relay to browser */
3324
                                        gateway->relay_rtp(session->handle, 0, buffer, bytes);
3325
                                        continue;
3326
                                } else if(session->media.audio_rtcp_fd != -1 && fds[i].fd == session->media.audio_rtcp_fd) {
3327
                                        /* Got something audio (RTCP) */
3328
                                        addrlen = sizeof(remote);
3329
                                        bytes = recvfrom(session->media.audio_rtcp_fd, buffer, 1500, 0, (struct sockaddr*)&remote, &addrlen);
3330
                                        //~ JANUS_LOG(LOG_VERB, "************************\nGot %d bytes on the audio RTCP channel...\n", bytes);
3331
                                        /* Is this SRTCP? */
3332
                                        if(session->media.has_srtp_remote) {
3333
                                                int buflen = bytes;
3334
                                                err_status_t res = srtp_unprotect_rtcp(session->media.audio_srtp_in, buffer, &buflen);
3335
                                                if(res != err_status_ok && res != err_status_replay_fail && res != err_status_replay_old) {
3336
                                                        JANUS_LOG(LOG_ERR, "[SIP-%s] Audio SRTCP unprotect error: %s (len=%d-->%d)\n",
3337
                                                                session->account.username, janus_sip_get_srtp_error(res), bytes, buflen);
3338
                                                        continue;
3339
                                                }
3340
                                                bytes = buflen;
3341
                                        }
3342
                                        /* Relay to browser */
3343
                                        gateway->relay_rtcp(session->handle, 0, buffer, bytes);
3344
                                        continue;
3345
                                } else if(session->media.video_rtp_fd != -1 && fds[i].fd == session->media.video_rtp_fd) {
3346
                                        /* Got something video (RTP) */
3347
                                        addrlen = sizeof(remote);
3348
                                        bytes = recvfrom(session->media.video_rtp_fd, buffer, 1500, 0, (struct sockaddr*)&remote, &addrlen);
3349
                                        //~ JANUS_LOG(LOG_VERB, "************************\nGot %d bytes on the video RTP channel...\n", bytes);
3350
                                        //~ rtp_header_t *rtp = (rtp_header_t *)buffer;
3351
                                        //~ JANUS_LOG(LOG_VERB, " ... parsed RTP packet (ssrc=%u, pt=%u, seq=%u, ts=%u)...\n",
3352
                                                //~ ntohl(rtp->ssrc), rtp->type, ntohs(rtp->seq_number), ntohl(rtp->timestamp));
3353
                                        if(session->media.video_ssrc_peer == 0) {
3354
                                                rtp_header *header = (rtp_header *)buffer;
3355
                                                session->media.video_ssrc_peer = ntohl(header->ssrc);
3356
                                                JANUS_LOG(LOG_VERB, "Got SIP peer video SSRC: %"SCNu32"\n", session->media.video_ssrc_peer);
3357
                                        }
3358
                                        /* Is this SRTP? */
3359
                                        if(session->media.has_srtp_remote) {
3360
                                                int buflen = bytes;
3361
                                                err_status_t res = srtp_unprotect(session->media.video_srtp_in, buffer, &buflen);
3362
                                                if(res != err_status_ok && res != err_status_replay_fail && res != err_status_replay_old) {
3363
                                                        rtp_header *header = (rtp_header *)buffer;
3364
                                                        guint32 timestamp = ntohl(header->timestamp);
3365
                                                        guint16 seq = ntohs(header->seq_number);
3366
                                                        JANUS_LOG(LOG_ERR, "[SIP-%s] Video SRTP unprotect error: %s (len=%d-->%d, ts=%"SCNu32", seq=%"SCNu16")\n",
3367
                                                                session->account.username, janus_sip_get_srtp_error(res), bytes, buflen, timestamp, seq);
3368
                                                        continue;
3369
                                                }
3370
                                                bytes = buflen;
3371
                                        }
3372
                                        /* Save the frame if we're recording */
3373
                                        janus_recorder_save_frame(session->vrc_peer, buffer, bytes);
3374
                                        /* Relay to browser */
3375
                                        gateway->relay_rtp(session->handle, 1, buffer, bytes);
3376
                                        continue;
3377
                                } else if(session->media.video_rtcp_fd != -1 && fds[i].fd == session->media.video_rtcp_fd) {
3378
                                        /* Got something video (RTCP) */
3379
                                        addrlen = sizeof(remote);
3380
                                        bytes = recvfrom(session->media.video_rtcp_fd, buffer, 1500, 0, (struct sockaddr*)&remote, &addrlen);
3381
                                        //~ JANUS_LOG(LOG_VERB, "************************\nGot %d bytes on the video RTCP channel...\n", bytes);
3382
                                        /* Is this SRTCP? */
3383
                                        if(session->media.has_srtp_remote) {
3384
                                                int buflen = bytes;
3385
                                                err_status_t res = srtp_unprotect_rtcp(session->media.video_srtp_in, buffer, &buflen);
3386
                                                if(res != err_status_ok && res != err_status_replay_fail && res != err_status_replay_old) {
3387
                                                        JANUS_LOG(LOG_ERR, "[SIP-%s] Video SRTP unprotect error: %s (len=%d-->%d)\n",
3388
                                                                session->account.username, janus_sip_get_srtp_error(res), bytes, buflen);
3389
                                                        continue;
3390
                                                }
3391
                                                bytes = buflen;
3392
                                        }
3393
                                        /* Relay to browser */
3394
                                        gateway->relay_rtcp(session->handle, 1, buffer, bytes);
3395
                                        continue;
3396
                                }
3397
                        }
3398
                }
3399
        }
3400
        if(session->media.audio_rtp_fd != -1) {
3401
                close(session->media.audio_rtp_fd);
3402
                session->media.audio_rtp_fd = -1;
3403
        }
3404
        if(session->media.audio_rtcp_fd != -1) {
3405
                close(session->media.audio_rtcp_fd);
3406
                session->media.audio_rtcp_fd = -1;
3407
        }
3408
        session->media.local_audio_rtp_port = 0;
3409
        session->media.local_audio_rtcp_port = 0;
3410
        session->media.audio_ssrc = 0;
3411
        if(session->media.video_rtp_fd != -1) {
3412
                close(session->media.video_rtp_fd);
3413
                session->media.video_rtp_fd = -1;
3414
        }
3415
        if(session->media.video_rtcp_fd != -1) {
3416
                close(session->media.video_rtcp_fd);
3417
                session->media.video_rtcp_fd = -1;
3418
        }
3419
        session->media.local_video_rtp_port = 0;
3420
        session->media.local_video_rtcp_port = 0;
3421
        session->media.video_ssrc = 0;
3422
        /* Clean up SRTP stuff, if needed */
3423
        janus_sip_srtp_cleanup(session);
3424
        /* Done */
3425
        JANUS_LOG(LOG_VERB, "Leaving SIP relay thread\n");
3426
        g_thread_unref(g_thread_self());
3427
        return NULL;
3428
}
3429

    
3430

    
3431
/* Sofia Event thread */
3432
gpointer janus_sip_sofia_thread(gpointer user_data) {
3433
        janus_sip_session *session = (janus_sip_session *)user_data;
3434
        if(session == NULL || session->account.username == NULL) {
3435
                g_thread_unref(g_thread_self());
3436
                return NULL;
3437
        }
3438
        JANUS_LOG(LOG_VERB, "Joining sofia loop thread (%s)...\n", session->account.username);
3439
        session->stack = g_malloc0(sizeof(ssip_t));
3440
        session->stack->session = session;
3441
        session->stack->s_nua = NULL;
3442
        session->stack->s_nh_r = NULL;
3443
        session->stack->s_nh_i = NULL;
3444
        session->stack->s_root = su_root_create(session->stack);
3445
        su_home_init(session->stack->s_home);
3446
        JANUS_LOG(LOG_VERB, "Setting up sofia stack (sip:%s@%s)\n", session->account.username, local_ip);
3447
        char sip_url[128];
3448
        char sips_url[128];
3449
        char *ipv6;
3450
        ipv6 = strstr(local_ip, ":");
3451
        g_snprintf(sip_url, sizeof(sip_url), "sip:%s%s%s:*", ipv6 ? "[" : "", local_ip, ipv6 ? "]" : "");
3452
        g_snprintf(sips_url, sizeof(sips_url), "sips:%s%s%s:*", ipv6 ? "[" : "", local_ip, ipv6 ? "]" : "");
3453
        char outbound_options[256] = "use-rport no-validate";
3454
        if(keepalive_interval > 0)
3455
                g_strlcat(outbound_options, " options-keepalive", sizeof(outbound_options));
3456
        if(!behind_nat)
3457
                g_strlcat(outbound_options, " no-natify", sizeof(outbound_options));
3458
        session->stack->s_nua = nua_create(session->stack->s_root,
3459
                                janus_sip_sofia_callback,
3460
                                session,
3461
                                SIPTAG_ALLOW_STR("INVITE, ACK, BYE, CANCEL, OPTIONS"),
3462
                                NUTAG_M_USERNAME(session->account.username),
3463
                                NUTAG_URL(sip_url),
3464
                                TAG_IF(session->account.sips, NUTAG_SIPS_URL(sips_url)),
3465
                                SIPTAG_USER_AGENT_STR(session->account.user_agent ? session->account.user_agent : user_agent),
3466
                                NUTAG_KEEPALIVE(keepalive_interval * 1000),        /* Sofia expects it in milliseconds */
3467
                                NUTAG_OUTBOUND(outbound_options),
3468
                                SIPTAG_SUPPORTED(NULL),
3469
                                TAG_NULL());
3470
        su_root_run(session->stack->s_root);
3471
        /* When we get here, we're done */
3472
        nua_destroy(session->stack->s_nua);
3473
        su_root_destroy(session->stack->s_root);
3474
        session->stack->s_root = NULL;
3475
        su_home_deinit(session->stack->s_home);
3476
        su_home_unref(session->stack->s_home);
3477
        su_deinit();
3478
        if (session->stack) {
3479
                g_free(session->stack);
3480
                session->stack = NULL;
3481
        }
3482
        //~ stop = 1;
3483
        JANUS_LOG(LOG_VERB, "Leaving sofia loop thread...\n");
3484
        g_thread_unref(g_thread_self());
3485
        /* Cleaning up and removing the session is done in a lazy way */
3486
        janus_mutex_lock(&sessions_mutex);
3487
        old_sessions = g_list_append(old_sessions, session);
3488
        janus_mutex_unlock(&sessions_mutex);
3489
        return NULL;
3490
}