var URL = window.URL || window.webkitURL;
function getCookie(key) {
var re = new RegExp("(?:(?:^|.*;\s*) ?" + key + "\s*\=\s*([^;]*).*$)|^.*$");
return document.cookie.replace(re, "$1");
function randomString(length, chars) {
for (var i = length; i > 0; --i)
result += chars[Math.round(Math.random() * (chars.length - 1))];
var token = getCookie('onsipToken');
token = randomString(32, ['0123456789',
'abcdefghijklmnopqrstuvwxyz',
'ABCDEFGHIJKLMNOPQRSTUVWXYZ'].join(''));
d.setTime(d.getTime() + 1000*60*60*24);
document.cookie = ('onsipToken=' + token + ';'
+ 'expires=' + d.toUTCString() + ';');
var domain = 'sipjs.onsip.com';
var aliceURI = 'alice.' + window.token + '@' + domain;
var bobURI = 'bob.' + window.token + '@' + domain;
function mediaOptions(audio, video, remoteRender, localRender) {
function createUA(callerURI, displayName) {
var userAgent = new SIP.UA(configuration);
function makeCall(userAgent, target, audio, video, remoteRender, localRender) {
var options = mediaOptions(audio, video, remoteRender, localRender);
var session = userAgent.invite('sip:' + target, options);
function setUpVideoInterface(userAgent, target, remoteRenderId, buttonId) {
var remoteRender = document.getElementById(remoteRenderId);
var button = document.getElementById(buttonId);
userAgent.on('invite', function (incomingSession) {
session = incomingSession;
var options = mediaOptions(false, true, remoteRender, null);
button.firstChild.nodeValue = 'hang up';
remoteRender.style.visibility = 'visible';
session.on('bye', function () {
button.firstChild.nodeValue = 'video';
remoteRender.style.visibility = 'hidden';
button.addEventListener('click', function () {
button.firstChild.nodeValue = 'video';
remoteRender.style.visibility = 'hidden';
button.firstChild.nodeValue = 'hang up';
remoteRender.style.visibility = 'visible';
session = makeCall(userAgent, target,
session.on('bye', function () {
button.firstChild.nodeValue = 'video';
remoteRender.style.visibility = 'hidden';
function setUpMessageInterface(userAgent, target,
messageRenderId, messageInputId, buttonId) {
var messageRender = document.getElementById(messageRenderId);
var messageInput = document.getElementById(messageInputId);
var button = document.getElementById(buttonId);
var msg = messageInput.value;
userAgent.message(target, msg);
userAgent.on('message', function (msg) {
if (messageRender.childElementCount > 0)
messageRender.removeChild(messageRender.children[0]);
var msgTag = createMsgTag(msg.remoteIdentity.displayName, msg.body);
messageRender.appendChild(msgTag);
button.addEventListener('click', function () {
messageInput.onkeydown = (function(e) {
if(e.keyCode == 13 && !e.shiftKey) {
function createMsgTag(from, msgBody) {
var msgTag = document.createElement('p');
msgTag.className = 'message';
var fromTag = document.createElement('span');
fromTag.className = 'message-from';
fromTag.appendChild(document.createTextNode(from + ':'));
var msgBodyTag = document.createElement('span');
msgBodyTag.className = 'message-body';
msgBodyTag.appendChild(document.createTextNode(' ' + msgBody));
msgTag.appendChild(fromTag);
msgTag.appendChild(msgBodyTag);
function createDataUA(callerURI, displayName) {
var dataURI = 'data.' + callerURI;
displayName: displayName,
mediaHandlerFactory: function mediaHandlerFactory(session, options) {
SIP.WebRTC.isSupported();
var self = new SIP.WebRTC.MediaHandler(session, {
acquire: function (onSuccess) {
setTimeout(onSuccess.bind(null, {}), 0);
release: function (stream) {
self.addStream = function addStream(stream, success, failure) {
return new SIP.UA(configuration);
function setUpDataInterface(userAgent, target,
var dataTarget = 'data.' + target;
var dataRender = document.getElementById(dataRenderId);
var fileInput = document.getElementById(fileInputId);
var filenameDisplay = document.getElementById(filenameDisplayId);
var dataShareButton = document.getElementById(dataShareButtonId);
var errorMsgContainer = document.getElementById(errorMsgContainerId);
if (errorMsgContainer.childNodes.length === 0) {
errorMsgContainer.appendChild(document.createTextNode(''));
var receivedFileMetadata;
var maxChunkSize = 16000;
userAgent.on('invite', function (session) {
session.mediaHandler.on('dataChannel', function (dataChannel) {
dataChannel.onmessage = function (event) {
if (typeof(event.data) === 'string' && event.data === '\n') {
receivedFile = new Blob([receivedFileData],
{type: receivedFileMetadata.type});
var fileUrl = URL.createObjectURL(receivedFile);
var msgTag = createDataMsgTag(
session.remoteIdentity.displayName,
receivedFileMetadata.name,
dataRender.removeChild(dataRender.children[0]);
dataRender.appendChild(msgTag);
} else if (typeof(event.data) === 'string') {
receivedFileMetadata = JSON.parse(event.data);
receivedFileData = event.data;
fileInput.addEventListener('change', function (event) {
var tmpFile = event.target.files[0];
if (tmpFile !== undefined && tmpFile !== file) {
var filename = file.name;
filenameDisplay.childNodes[0].nodeValue = filename;
if (file.size <= maxChunkSize) {
errorMsgContainer.childNodes[0].nodeValue = '';
var reader = new FileReader();
reader.onload = (function (e) {
loadedFile = e.target.result;
reader.readAsArrayBuffer(file);
var errorStr = 'File too large to send using demo (chunking not supported)';
errorMsgContainer.childNodes[0].nodeValue = errorStr;
dataShareButton.addEventListener('click', function () {
if (loadedFile !== null) {
session = userAgent.invite('sip:' + dataTarget, options);
session.mediaHandler.on('dataChannel', function (dataChannel) {
dataChannel.onopen = (function () {
dataChannel.send(JSON.stringify({
dataChannel.send(loadedFile);
session.on('bye', function (req) {
var msgTag = createDataMsgTag(
userAgent.configuration.displayName,
URL.createObjectURL(file)
dataRender.removeChild(dataRender.children[0]);
dataRender.appendChild(msgTag);
function createDataMsgTag(from, msgBody, filename, dataURI) {
var msgTag = createMsgTag(from, msgBody + ' ');
var fileLinkTag = document.createElement('a');
fileLinkTag.className = 'message-link';
fileLinkTag.setAttribute('href', dataURI);
fileLinkTag.setAttribute('download', filename);
fileLinkTag.appendChild(document.createTextNode(filename));
msgTag.appendChild(fileLinkTag);
if (SIP.WebRTC.isSupported()) {
window.aliceUA = createUA(aliceURI, aliceName);
window.bobUA = createUA(bobURI, bobName);
window.aliceDataUA = createDataUA(aliceURI, aliceName);
window.bobDataUA = createDataUA(bobURI, bobName);
var registrationFailed = false;
var markAsRegistered = function () {
if (numRegistered >= numToRegister && !registrationFailed) {
var failRegistration = function () {
registrationFailed = true;
aliceUA.on('registered', markAsRegistered);
bobUA.on('registered', markAsRegistered);
aliceDataUA.on('registered', markAsRegistered);
bobDataUA.on('registered', markAsRegistered);
aliceUA.on('registrationFailed', failRegistration);
bobUA.on('registrationFailed', failRegistration);
aliceDataUA.on('registrationFailed', failRegistration);
bobDataUA.on('registrationFailed', failRegistration);
window.onunload = function () {
function setupInterfaces() {
setUpVideoInterface(aliceUA, bobURI, 'video-of-bob', 'alice-video-button');
setUpVideoInterface(bobUA, aliceURI, 'video-of-alice', 'bob-video-button');
setUpMessageInterface(aliceUA, bobURI,
setUpMessageInterface(bobUA, aliceURI,
setUpDataInterface(aliceDataUA, bobURI,
'alice-file-choose-input',
'alice-data-share-button',
setUpDataInterface(bobDataUA, aliceURI,
function failInterfaceSetup() {
alert('Max registration limit hit. Could not register all user agents, so they cannot communicate. The app is disabled.');
var button = document.querySelector('button.file-choose-button');
var fileInputs = document.querySelectorAll('input.file-choose-button');
var width = button.style.width;
var height = button.style.height;
var paddingLeft = button.style.paddingLeft;
var paddingRight = button.style.paddingRight;
var paddingTop = button.style.paddingTop;
var paddingBottom = button.style.paddingBottom;
for (var i=0; i < fileInputs.length; i++) {
var input = fileInputs[i];
input.style.width = width;
input.style.height = height;
input.style.paddingLeft = paddingLeft;
input.style.paddingRight = paddingRight;
input.style.paddingTop = paddingTop;
input.style.paddingBottom = paddingBottom;