Fork me on GitHub
Data Structures | Macros | Typedefs | Enumerations | Functions | Variables
janus_sip.c File Reference

Janus SIP plugin. More...

#include "plugin.h"
#include <arpa/inet.h>
#include <net/if.h>
#include <jansson.h>
#include <sofia-sip/msg_header.h>
#include <sofia-sip/nua.h>
#include <sofia-sip/sdp.h>
#include <sofia-sip/sip_status.h>
#include <sofia-sip/url.h>
#include <sofia-sip/tport_tag.h>
#include <sofia-sip/su_log.h>
#include "../debug.h"
#include "../apierror.h"
#include "../config.h"
#include "../mutex.h"
#include "../record.h"
#include "../rtp.h"
#include "../rtcp.h"
#include "../sdp-utils.h"
#include "../utils.h"
#include "../ip-utils.h"
Include dependency graph for janus_sip.c:

Data Structures

struct  janus_sip_message
 
struct  janus_sip_account
 
struct  janus_sip_media
 
struct  janus_sip_session
 
struct  ssip_s
 
struct  janus_sip_uri_t
 

Macros

#define JANUS_SIP_VERSION   6
 
#define JANUS_SIP_VERSION_STRING   "0.0.6"
 
#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."
 
#define JANUS_SIP_NAME   "JANUS SIP plugin"
 
#define JANUS_SIP_AUTHOR   "Meetecho s.r.l."
 
#define JANUS_SIP_PACKAGE   "janus.plugin.sip"
 
#define JANUS_DEFAULT_REGISTER_TTL   3600
 
#define SU_ROOT_MAGIC_T   ssip_t
 
#define NUA_MAGIC_T   ssip_t
 
#define NUA_HMAGIC_T   ssip_oper_t
 
#define JANUS_SIP_URI_MAXLEN   1024
 
#define JANUS_SIP_ERROR_UNKNOWN_ERROR   499
 
#define JANUS_SIP_ERROR_NO_MESSAGE   440
 
#define JANUS_SIP_ERROR_INVALID_JSON   441
 
#define JANUS_SIP_ERROR_INVALID_REQUEST   442
 
#define JANUS_SIP_ERROR_MISSING_ELEMENT   443
 
#define JANUS_SIP_ERROR_INVALID_ELEMENT   444
 
#define JANUS_SIP_ERROR_ALREADY_REGISTERED   445
 
#define JANUS_SIP_ERROR_INVALID_ADDRESS   446
 
#define JANUS_SIP_ERROR_WRONG_STATE   447
 
#define JANUS_SIP_ERROR_MISSING_SDP   448
 
#define JANUS_SIP_ERROR_LIBSOFIA_ERROR   449
 
#define JANUS_SIP_ERROR_IO_ERROR   450
 
#define JANUS_SIP_ERROR_RECORDING_ERROR   451
 
#define JANUS_SIP_ERROR_TOO_STRICT   452
 

Typedefs

typedef struct janus_sip_message janus_sip_message
 
typedef struct ssip_s ssip_t
 
typedef struct ssip_oper_s ssip_oper_t
 
typedef struct janus_sip_account janus_sip_account
 
typedef struct janus_sip_media janus_sip_media
 
typedef struct janus_sip_session janus_sip_session
 

Enumerations

enum  janus_sip_registration_status {
  janus_sip_registration_status_disabled = -2, janus_sip_registration_status_failed = -1, janus_sip_registration_status_unregistered = 0, janus_sip_registration_status_registering,
  janus_sip_registration_status_registered, janus_sip_registration_status_unregistering
}
 
enum  janus_sip_call_status {
  janus_sip_call_status_idle = 0, janus_sip_call_status_inviting, janus_sip_call_status_invited, janus_sip_call_status_incall,
  janus_sip_call_status_closing
}
 
enum  janus_sip_secret_type { janus_sip_secret_type_plaintext = 1, janus_sip_secret_type_hashed = 2, janus_sip_secret_type_unknown }
 

Functions

janus_plugincreate (void)
 
int janus_sip_init (janus_callbacks *callback, const char *config_path)
 
void janus_sip_destroy (void)
 
int janus_sip_get_api_compatibility (void)
 
int janus_sip_get_version (void)
 
const char * janus_sip_get_version_string (void)
 
const char * janus_sip_get_description (void)
 
const char * janus_sip_get_name (void)
 
const char * janus_sip_get_author (void)
 
const char * janus_sip_get_package (void)
 
void janus_sip_create_session (janus_plugin_session *handle, int *error)
 
struct janus_plugin_resultjanus_sip_handle_message (janus_plugin_session *handle, char *transaction, json_t *message, json_t *jsep)
 
void janus_sip_setup_media (janus_plugin_session *handle)
 
void janus_sip_incoming_rtp (janus_plugin_session *handle, int video, char *buf, int len)
 
void janus_sip_incoming_rtcp (janus_plugin_session *handle, int video, char *buf, int len)
 
void janus_sip_hangup_media (janus_plugin_session *handle)
 
void janus_sip_destroy_session (janus_plugin_session *handle, int *error)
 
json_t * janus_sip_query_session (janus_plugin_session *handle)
 
gpointer janus_sip_sofia_thread (gpointer user_data)
 
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[])
 
void janus_sip_sdp_process (janus_sip_session *session, janus_sdp *sdp, gboolean answer, gboolean update, gboolean *changed)
 
char * janus_sip_sdp_manipulate (janus_sip_session *session, janus_sdp *sdp, gboolean answer)
 

Variables

char sofia_log [2048]
 
char call_id [255]
 
gboolean skip = FALSE
 
gboolean started = FALSE
 
gboolean append = FALSE
 

Detailed Description

Janus SIP plugin.

Author
Lorenzo Miniero loren.nosp@m.zo@m.nosp@m.eetec.nosp@m.ho.c.nosp@m.om

This is a simple SIP plugin for Janus, allowing WebRTC peers to register at a SIP server (e.g., Asterisk) and call SIP user agents through the gateway. Specifically, when attaching to the plugin peers are requested to provide their SIP server credentials, i.e., the address of the SIP server and their username/secret. This results in the plugin registering at the SIP server and acting as a SIP client on behalf of the web peer. Most of the SIP states and lifetime are masked by the plugin, and only the relevant events (e.g., INVITEs and BYEs) and functionality (call, hangup) are made available to the web peer: peers can call extensions at the SIP server or wait for incoming INVITEs, and during a call they can send DTMF tones. Calls can do plain RTP or SDES-SRTP.

The concept behind this plugin is to allow different web pages associated to the same peer, and hence the same SIP user, to attach to the plugin at the same time and yet just do a SIP REGISTER once. The same should apply for calls: while an incoming call would be notified to all the web UIs associated to the peer, only one would be able to pick up and answer, in pretty much the same way as SIP forking works but without the need to fork in the same place. This specific functionality, though, has not been implemented as of yet.

Todo:
Only Asterisk and Kamailio have been tested as a SIP server, and specifically only with basic audio calls: this plugin needs some work to make it more stable and reliable.

SIP Plugin API

All requests you can send in the SIP Plugin API are asynchronous, which means all responses (successes and errors) will be delivered as events with the same transaction.

The supported requests are register , call , accept, hold , unhold and hangup . register can be used, as the name suggests, to register a username at a SIP registrar to call and be called; call is used to send an INVITE to a different SIP URI through the plugin, while accept is used to accept the call in case one is invited instead of inviting; hold and unhold can be used respectively to put a call on-hold and to resume it; finally, hangup can be used to terminate the communication at any time, either to hangup (BYE) an ongoing call or to cancel/decline (CANCEL/BYE) a call that hasn't started yet.

Actual API docs: TBD.

Plugins

Macro Definition Documentation

◆ JANUS_DEFAULT_REGISTER_TTL

#define JANUS_DEFAULT_REGISTER_TTL   3600

◆ JANUS_SIP_AUTHOR

#define JANUS_SIP_AUTHOR   "Meetecho s.r.l."

◆ JANUS_SIP_DESCRIPTION

#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."

◆ JANUS_SIP_ERROR_ALREADY_REGISTERED

#define JANUS_SIP_ERROR_ALREADY_REGISTERED   445

◆ JANUS_SIP_ERROR_INVALID_ADDRESS

#define JANUS_SIP_ERROR_INVALID_ADDRESS   446

◆ JANUS_SIP_ERROR_INVALID_ELEMENT

#define JANUS_SIP_ERROR_INVALID_ELEMENT   444

◆ JANUS_SIP_ERROR_INVALID_JSON

#define JANUS_SIP_ERROR_INVALID_JSON   441

◆ JANUS_SIP_ERROR_INVALID_REQUEST

#define JANUS_SIP_ERROR_INVALID_REQUEST   442

◆ JANUS_SIP_ERROR_IO_ERROR

#define JANUS_SIP_ERROR_IO_ERROR   450

◆ JANUS_SIP_ERROR_LIBSOFIA_ERROR

#define JANUS_SIP_ERROR_LIBSOFIA_ERROR   449

◆ JANUS_SIP_ERROR_MISSING_ELEMENT

#define JANUS_SIP_ERROR_MISSING_ELEMENT   443

◆ JANUS_SIP_ERROR_MISSING_SDP

#define JANUS_SIP_ERROR_MISSING_SDP   448

◆ JANUS_SIP_ERROR_NO_MESSAGE

#define JANUS_SIP_ERROR_NO_MESSAGE   440

◆ JANUS_SIP_ERROR_RECORDING_ERROR

#define JANUS_SIP_ERROR_RECORDING_ERROR   451

◆ JANUS_SIP_ERROR_TOO_STRICT

#define JANUS_SIP_ERROR_TOO_STRICT   452

◆ JANUS_SIP_ERROR_UNKNOWN_ERROR

#define JANUS_SIP_ERROR_UNKNOWN_ERROR   499

◆ JANUS_SIP_ERROR_WRONG_STATE

#define JANUS_SIP_ERROR_WRONG_STATE   447

◆ JANUS_SIP_NAME

#define JANUS_SIP_NAME   "JANUS SIP plugin"

◆ JANUS_SIP_PACKAGE

#define JANUS_SIP_PACKAGE   "janus.plugin.sip"

◆ JANUS_SIP_URI_MAXLEN

#define JANUS_SIP_URI_MAXLEN   1024

◆ JANUS_SIP_VERSION

#define JANUS_SIP_VERSION   6

◆ JANUS_SIP_VERSION_STRING

#define JANUS_SIP_VERSION_STRING   "0.0.6"

◆ NUA_HMAGIC_T

#define NUA_HMAGIC_T   ssip_oper_t

◆ NUA_MAGIC_T

#define NUA_MAGIC_T   ssip_t

◆ SU_ROOT_MAGIC_T

#define SU_ROOT_MAGIC_T   ssip_t

Typedef Documentation

◆ janus_sip_account

◆ janus_sip_media

◆ janus_sip_message

◆ janus_sip_session

◆ ssip_oper_t

typedef struct ssip_oper_s ssip_oper_t

◆ ssip_t

typedef struct ssip_s ssip_t

Enumeration Type Documentation

◆ janus_sip_call_status

Enumerator
janus_sip_call_status_idle 
janus_sip_call_status_inviting 
janus_sip_call_status_invited 
janus_sip_call_status_incall 
janus_sip_call_status_closing 

◆ janus_sip_registration_status

Enumerator
janus_sip_registration_status_disabled 
janus_sip_registration_status_failed 
janus_sip_registration_status_unregistered 
janus_sip_registration_status_registering 
janus_sip_registration_status_registered 
janus_sip_registration_status_unregistering 

◆ janus_sip_secret_type

Enumerator
janus_sip_secret_type_plaintext 
janus_sip_secret_type_hashed 
janus_sip_secret_type_unknown 

Function Documentation

◆ create()

janus_plugin* create ( void  )

◆ janus_sip_create_session()

void janus_sip_create_session ( janus_plugin_session handle,
int *  error 
)

◆ janus_sip_destroy()

void janus_sip_destroy ( void  )

◆ janus_sip_destroy_session()

void janus_sip_destroy_session ( janus_plugin_session handle,
int *  error 
)

◆ janus_sip_get_api_compatibility()

int janus_sip_get_api_compatibility ( void  )

◆ janus_sip_get_author()

const char * janus_sip_get_author ( void  )

◆ janus_sip_get_description()

const char * janus_sip_get_description ( void  )

◆ janus_sip_get_name()

const char * janus_sip_get_name ( void  )

◆ janus_sip_get_package()

const char * janus_sip_get_package ( void  )

◆ janus_sip_get_version()

int janus_sip_get_version ( void  )

◆ janus_sip_get_version_string()

const char * janus_sip_get_version_string ( void  )

◆ janus_sip_handle_message()

struct janus_plugin_result * janus_sip_handle_message ( janus_plugin_session handle,
char *  transaction,
json_t *  message,
json_t *  jsep 
)

◆ janus_sip_hangup_media()

void janus_sip_hangup_media ( janus_plugin_session handle)

◆ janus_sip_incoming_rtcp()

void janus_sip_incoming_rtcp ( janus_plugin_session handle,
int  video,
char *  buf,
int  len 
)

◆ janus_sip_incoming_rtp()

void janus_sip_incoming_rtp ( janus_plugin_session handle,
int  video,
char *  buf,
int  len 
)

◆ janus_sip_init()

int janus_sip_init ( janus_callbacks callback,
const char *  config_path 
)

◆ janus_sip_query_session()

json_t * janus_sip_query_session ( janus_plugin_session handle)

◆ janus_sip_sdp_manipulate()

char * janus_sip_sdp_manipulate ( janus_sip_session session,
janus_sdp sdp,
gboolean  answer 
)

◆ janus_sip_sdp_process()

void janus_sip_sdp_process ( janus_sip_session session,
janus_sdp sdp,
gboolean  answer,
gboolean  update,
gboolean *  changed 
)

◆ janus_sip_setup_media()

void janus_sip_setup_media ( janus_plugin_session handle)

◆ janus_sip_sofia_callback()

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[] 
)

◆ janus_sip_sofia_thread()

gpointer janus_sip_sofia_thread ( gpointer  user_data)

Variable Documentation

◆ append

gboolean append = FALSE

◆ call_id

char call_id[255]

◆ skip

gboolean skip = FALSE

◆ sofia_log

char sofia_log[2048]

◆ started

gboolean started = FALSE