You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

28427 lines
813 KiB

/*
* SimpleSIP v3.10.1
* the Javascript SIP library
* Copyright: 2012-2023
* Homepage: https://SimpleSIP.net
* License: MIT
*/
(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.SimpleSIP = f()}})(function(){var define,module,exports;return (function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i<t.length;i++)o(t[i]);return o}return r})()({1:[function(require,module,exports){
"use strict";
function _createForOfIteratorHelper(o, allowArrayLike) { var it; if (typeof Symbol === "undefined" || o[Symbol.iterator] == null) { if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = o[Symbol.iterator](); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it["return"] != null) it["return"](); } finally { if (didErr) throw err; } } }; }
function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }
var Utils = require('./Utils');
var SimpleSIP_C = require('./Constants');
var Grammar = require('./Grammar');
var URI = require('./URI');
var Socket = require('./Socket');
var Exceptions = require('./Exceptions'); // Default settings.
exports.settings = {
// SIP authentication.
authorization_user: null,
password: null,
realm: null,
ha1: null,
authorization_jwt: null,
// SIP account.
display_name: null,
uri: null,
contact_uri: null,
// SIP instance id (GRUU).
instance_id: null,
// Preloaded SIP Route header field.
use_preloaded_route: false,
// Session parameters.
session_timers: true,
session_timers_refresh_method: SimpleSIP_C.UPDATE,
session_timers_force_refresher: false,
no_answer_timeout: 60,
// Registration parameters.
register: true,
register_expires: 600,
registrar_server: null,
// Connection options.
sockets: null,
connection_recovery_max_interval: SimpleSIP_C.CONNECTION_RECOVERY_MAX_INTERVAL,
connection_recovery_min_interval: SimpleSIP_C.CONNECTION_RECOVERY_MIN_INTERVAL,
// Global extra headers, to be added to every request and response
extra_headers: null,
/*
* Host address.
* Value to be set in Via sent_by and host part of Contact FQDN.
*/
via_host: "".concat(Utils.createRandomToken(12), ".invalid")
}; // Configuration checks.
var checks = {
mandatory: {
sockets: function sockets(_sockets2) {
/* Allow defining sockets parameter as:
* Socket: socket
* Array of Socket: [socket1, socket2]
* Array of Objects: [{socket: socket1, weight:1}, {socket: Socket2, weight:0}]
* Array of Objects and Socket: [{socket: socket1}, socket2]
*/
var _sockets = [];
if (Socket.isSocket(_sockets2)) {
_sockets.push({
socket: _sockets2
});
} else if (Array.isArray(_sockets2) && _sockets2.length) {
var _iterator = _createForOfIteratorHelper(_sockets2),
_step;
try {
for (_iterator.s(); !(_step = _iterator.n()).done;) {
var socket = _step.value;
if (Object.prototype.hasOwnProperty.call(socket, 'socket') && Socket.isSocket(socket.socket)) {
_sockets.push(socket);
} else if (Socket.isSocket(socket)) {
_sockets.push({
socket: socket
});
}
}
} catch (err) {
_iterator.e(err);
} finally {
_iterator.f();
}
} else {
return;
}
return _sockets;
},
uri: function uri(_uri) {
if (!/^sip:/i.test(_uri)) {
_uri = "".concat(SimpleSIP_C.SIP, ":").concat(_uri);
}
var parsed = URI.parse(_uri);
if (!parsed) {
return;
} else if (!parsed.user) {
return;
} else {
return parsed;
}
}
},
optional: {
authorization_user: function authorization_user(_authorization_user) {
if (Grammar.parse("\"".concat(_authorization_user, "\""), 'quoted_string') === -1) {
return;
} else {
return _authorization_user;
}
},
authorization_jwt: function authorization_jwt(_authorization_jwt) {
if (typeof _authorization_jwt === 'string') {
return _authorization_jwt;
}
},
user_agent: function user_agent(_user_agent) {
if (typeof _user_agent === 'string') {
return _user_agent;
}
},
connection_recovery_max_interval: function connection_recovery_max_interval(_connection_recovery_max_interval) {
if (Utils.isDecimal(_connection_recovery_max_interval)) {
var value = Number(_connection_recovery_max_interval);
if (value > 0) {
return value;
}
}
},
connection_recovery_min_interval: function connection_recovery_min_interval(_connection_recovery_min_interval) {
if (Utils.isDecimal(_connection_recovery_min_interval)) {
var value = Number(_connection_recovery_min_interval);
if (value > 0) {
return value;
}
}
},
contact_uri: function contact_uri(_contact_uri) {
if (typeof _contact_uri === 'string') {
var uri = Grammar.parse(_contact_uri, 'SIP_URI');
if (uri !== -1) {
return uri;
}
}
},
display_name: function display_name(_display_name) {
return _display_name;
},
instance_id: function instance_id(_instance_id) {
if (/^uuid:/i.test(_instance_id)) {
_instance_id = _instance_id.substr(5);
}
if (Grammar.parse(_instance_id, 'uuid') === -1) {
return;
} else {
return _instance_id;
}
},
no_answer_timeout: function no_answer_timeout(_no_answer_timeout) {
if (Utils.isDecimal(_no_answer_timeout)) {
var value = Number(_no_answer_timeout);
if (value > 0) {
return value;
}
}
},
session_timers: function session_timers(_session_timers) {
if (typeof _session_timers === 'boolean') {
return _session_timers;
}
},
session_timers_refresh_method: function session_timers_refresh_method(method) {
if (typeof method === 'string') {
method = method.toUpperCase();
if (method === SimpleSIP_C.INVITE || method === SimpleSIP_C.UPDATE) {
return method;
}
}
},
session_timers_force_refresher: function session_timers_force_refresher(_session_timers_force_refresher) {
if (typeof _session_timers_force_refresher === 'boolean') {
return _session_timers_force_refresher;
}
},
password: function password(_password) {
return String(_password);
},
realm: function realm(_realm) {
return String(_realm);
},
ha1: function ha1(_ha) {
return String(_ha);
},
register: function register(_register) {
if (typeof _register === 'boolean') {
return _register;
}
},
register_expires: function register_expires(_register_expires) {
if (Utils.isDecimal(_register_expires)) {
var value = Number(_register_expires);
if (value > 0) {
return value;
}
}
},
registrar_server: function registrar_server(_registrar_server) {
if (!/^sip:/i.test(_registrar_server)) {
_registrar_server = "".concat(SimpleSIP_C.SIP, ":").concat(_registrar_server);
}
var parsed = URI.parse(_registrar_server);
if (!parsed) {
return;
} else if (parsed.user) {
return;
} else {
return parsed;
}
},
use_preloaded_route: function use_preloaded_route(_use_preloaded_route) {
if (typeof _use_preloaded_route === 'boolean') {
return _use_preloaded_route;
}
},
extra_headers: function extra_headers(_extra_headers) {
var _extraHeaders = [];
if (Array.isArray(_extra_headers) && _extra_headers.length) {
var _iterator2 = _createForOfIteratorHelper(_extra_headers),
_step2;
try {
for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
var header = _step2.value;
if (typeof header === 'string') {
_extraHeaders.push(header);
}
}
} catch (err) {
_iterator2.e(err);
} finally {
_iterator2.f();
}
} else {
return;
}
return _extraHeaders;
}
}
};
exports.load = function (dst, src) {
// Check Mandatory parameters.
for (var parameter in checks.mandatory) {
if (!src.hasOwnProperty(parameter)) {
throw new Exceptions.ConfigurationError(parameter);
} else {
var value = src[parameter];
var checked_value = checks.mandatory[parameter](value);
if (checked_value !== undefined) {
dst[parameter] = checked_value;
} else {
throw new Exceptions.ConfigurationError(parameter, value);
}
}
} // Check Optional parameters.
for (var _parameter in checks.optional) {
if (src.hasOwnProperty(_parameter)) {
var _value = src[_parameter];
/* If the parameter value is null, empty string, undefined, empty array
* or it's a number with NaN value, then apply its default value.
*/
if (Utils.isEmpty(_value)) {
continue;
}
var _checked_value = checks.optional[_parameter](_value);
if (_checked_value !== undefined) {
dst[_parameter] = _checked_value;
} else {
throw new Exceptions.ConfigurationError(_parameter, _value);
}
}
}
};
},{"./Constants":2,"./Exceptions":6,"./Grammar":7,"./Socket":22,"./URI":27,"./Utils":28}],2:[function(require,module,exports){
"use strict";
var pkg = require('../package.json');
module.exports = {
USER_AGENT: "".concat(pkg.title, " ").concat(pkg.version),
// SIP scheme.
SIP: 'sip',
SIPS: 'sips',
// End and Failure causes.
causes: {
// Generic error causes.
CONNECTION_ERROR: 'Connection Error',
REQUEST_TIMEOUT: 'Request Timeout',
SIP_FAILURE_CODE: 'SIP Failure Code',
INTERNAL_ERROR: 'Internal Error',
// SIP error causes.
BUSY: 'Busy',
REJECTED: 'Rejected',
REDIRECTED: 'Redirected',
UNAVAILABLE: 'Unavailable',
NOT_FOUND: 'Not Found',
ADDRESS_INCOMPLETE: 'Address Incomplete',
INCOMPATIBLE_SDP: 'Incompatible SDP',
MISSING_SDP: 'Missing SDP',
AUTHENTICATION_ERROR: 'Authentication Error',
// Session error causes.
BYE: 'Terminated',
WEBRTC_ERROR: 'WebRTC Error',
CANCELED: 'Canceled',
NO_ANSWER: 'No Answer',
EXPIRES: 'Expires',
NO_ACK: 'No ACK',
DIALOG_ERROR: 'Dialog Error',
USER_DENIED_MEDIA_ACCESS: 'User Denied Media Access',
BAD_MEDIA_DESCRIPTION: 'Bad Media Description',
RTP_TIMEOUT: 'RTP Timeout'
},
SIP_ERROR_CAUSES: {
REDIRECTED: [300, 301, 302, 305, 380],
BUSY: [486, 600],
REJECTED: [403, 603],
NOT_FOUND: [404, 604],
UNAVAILABLE: [480, 410, 408, 430],
ADDRESS_INCOMPLETE: [484, 424],
INCOMPATIBLE_SDP: [488, 606],
AUTHENTICATION_ERROR: [401, 407]
},
// SIP Methods.
ACK: 'ACK',
BYE: 'BYE',
CANCEL: 'CANCEL',
INFO: 'INFO',
INVITE: 'INVITE',
MESSAGE: 'MESSAGE',
NOTIFY: 'NOTIFY',
OPTIONS: 'OPTIONS',
REGISTER: 'REGISTER',
REFER: 'REFER',
UPDATE: 'UPDATE',
SUBSCRIBE: 'SUBSCRIBE',
// DTMF transport methods.
DTMF_TRANSPORT: {
INFO: 'INFO',
RFC2833: 'RFC2833'
},
/* SIP Response Reasons
* DOC: https://www.iana.org/assignments/sip-parameters
* Copied from https://github.com/versatica/OverSIP/blob/master/lib/oversip/sip/constants.rb#L7
*/
REASON_PHRASE: {
100: 'Trying',
180: 'Ringing',
181: 'Call Is Being Forwarded',
182: 'Queued',
183: 'Session Progress',
199: 'Early Dialog Terminated',
// draft-ietf-sipcore-199
200: 'OK',
202: 'Accepted',
// RFC 3265
204: 'No Notification',
// RFC 5839
300: 'Multiple Choices',
301: 'Moved Permanently',
302: 'Moved Temporarily',
305: 'Use Proxy',
380: 'Alternative Service',
400: 'Bad Request',
401: 'Unauthorized',
402: 'Payment Required',
403: 'Forbidden',
404: 'Not Found',
405: 'Method Not Allowed',
406: 'Not Acceptable',
407: 'Proxy Authentication Required',
408: 'Request Timeout',
410: 'Gone',
412: 'Conditional Request Failed',
// RFC 3903
413: 'Request Entity Too Large',
414: 'Request-URI Too Long',
415: 'Unsupported Media Type',
416: 'Unsupported URI Scheme',
417: 'Unknown Resource-Priority',
// RFC 4412
420: 'Bad Extension',
421: 'Extension Required',
422: 'Session Interval Too Small',
// RFC 4028
423: 'Interval Too Brief',
424: 'Bad Location Information',
// RFC 6442
428: 'Use Identity Header',
// RFC 4474
429: 'Provide Referrer Identity',
// RFC 3892
430: 'Flow Failed',
// RFC 5626
433: 'Anonymity Disallowed',
// RFC 5079
436: 'Bad Identity-Info',
// RFC 4474
437: 'Unsupported Certificate',
// RFC 4744
438: 'Invalid Identity Header',
// RFC 4744
439: 'First Hop Lacks Outbound Support',
// RFC 5626
440: 'Max-Breadth Exceeded',
// RFC 5393
469: 'Bad Info Package',
// draft-ietf-sipcore-info-events
470: 'Consent Needed',
// RFC 5360
478: 'Unresolvable Destination',
// Custom code copied from Kamailio.
480: 'Temporarily Unavailable',
481: 'Call/Transaction Does Not Exist',
482: 'Loop Detected',
483: 'Too Many Hops',
484: 'Address Incomplete',
485: 'Ambiguous',
486: 'Busy Here',
487: 'Request Terminated',
488: 'Not Acceptable Here',
489: 'Bad Event',
// RFC 3265
491: 'Request Pending',
493: 'Undecipherable',
494: 'Security Agreement Required',
// RFC 3329
500: 'SimpleSIP Internal Error',
501: 'Not Implemented',
502: 'Bad Gateway',
503: 'Service Unavailable',
504: 'Server Time-out',
505: 'Version Not Supported',
513: 'Message Too Large',
580: 'Precondition Failure',
// RFC 3312
600: 'Busy Everywhere',
603: 'Decline',
604: 'Does Not Exist Anywhere',
606: 'Not Acceptable'
},
ALLOWED_METHODS: 'INVITE,ACK,CANCEL,BYE,UPDATE,MESSAGE,OPTIONS,REFER,INFO,NOTIFY',
ACCEPTED_BODY_TYPES: 'application/sdp, application/dtmf-relay',
MAX_FORWARDS: 69,
SESSION_EXPIRES: 90,
MIN_SESSION_EXPIRES: 60,
CONNECTION_RECOVERY_MAX_INTERVAL: 30,
CONNECTION_RECOVERY_MIN_INTERVAL: 2
};
},{"../package.json":40}],3:[function(require,module,exports){
"use strict";
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }
var Logger = require('./Logger');
var SIPMessage = require('./SIPMessage');
var SimpleSIP_C = require('./Constants');
var Transactions = require('./Transactions');
var Dialog_RequestSender = require('./Dialog/RequestSender');
var Utils = require('./Utils');
var logger = new Logger('Dialog');
var C = {
// Dialog states.
STATUS_EARLY: 1,
STATUS_CONFIRMED: 2,
STATUS_TERMINATED: 3
}; // RFC 3261 12.1.
module.exports = /*#__PURE__*/function () {
_createClass(Dialog, null, [{
key: "C",
// Expose C object.
get: function get() {
return C;
}
}]);
function Dialog(owner, message, type) {
var state = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : C.STATUS_CONFIRMED;
_classCallCheck(this, Dialog);
this._owner = owner;
this._ua = owner._ua;
this._uac_pending_reply = false;
this._uas_pending_reply = false;
if (!message.hasHeader('contact')) {
return {
error: 'unable to create a Dialog without Contact header field'
};
}
if (message instanceof SIPMessage.IncomingResponse) {
state = message.status_code < 200 ? C.STATUS_EARLY : C.STATUS_CONFIRMED;
}
var contact = message.parseHeader('contact'); // RFC 3261 12.1.1.
if (type === 'UAS') {
this._id = {
call_id: message.call_id,
local_tag: message.to_tag,
remote_tag: message.from_tag,
toString: function toString() {
return this.call_id + this.local_tag + this.remote_tag;
}
};
this._state = state;
this._remote_seqnum = message.cseq;
this._local_uri = message.parseHeader('to').uri;
this._remote_uri = message.parseHeader('from').uri;
this._remote_target = contact.uri;
this._route_set = message.getHeaders('record-route');
this._ack_seqnum = this._remote_seqnum;
} // RFC 3261 12.1.2.
else if (type === 'UAC') {
this._id = {
call_id: message.call_id,
local_tag: message.from_tag,
remote_tag: message.to_tag,
toString: function toString() {
return this.call_id + this.local_tag + this.remote_tag;
}
};
this._state = state;
this._local_seqnum = message.cseq;
this._local_uri = message.parseHeader('from').uri;
this._remote_uri = message.parseHeader('to').uri;
this._remote_target = contact.uri;
this._route_set = message.getHeaders('record-route').reverse();
this._ack_seqnum = null;
}
this._ua.newDialog(this);
logger.debug("new ".concat(type, " dialog created with status ").concat(this._state === C.STATUS_EARLY ? 'EARLY' : 'CONFIRMED'));
}
_createClass(Dialog, [{
key: "isTerminated",
value: function isTerminated() {
return this._status === C.STATUS_TERMINATED;
}
}, {
key: "update",
value: function update(message, type) {
this._state = C.STATUS_CONFIRMED;
logger.debug("dialog ".concat(this._id.toString(), " changed to CONFIRMED state"));
if (type === 'UAC') {
// RFC 3261 13.2.2.4.
this._route_set = message.getHeaders('record-route').reverse();
}
}
}, {
key: "terminate",
value: function terminate() {
logger.debug("dialog ".concat(this._id.toString(), " deleted"));
this._ua.destroyDialog(this);
this._state = C.STATUS_TERMINATED;
}
}, {
key: "sendRequest",
value: function sendRequest(method) {
var _this = this;
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
var extraHeaders = Utils.cloneArray(options.extraHeaders);
var eventHandlers = Utils.cloneObject(options.eventHandlers);
var body = options.body || null;
var request = this._createRequest(method, extraHeaders, body); // Increase the local CSeq on authentication.
eventHandlers.onAuthenticated = function () {
_this._local_seqnum += 1;
};
var request_sender = new Dialog_RequestSender(this, request, eventHandlers);
request_sender.send(); // Return the instance of OutgoingRequest.
return request;
}
}, {
key: "receiveRequest",
value: function receiveRequest(request) {
// Check in-dialog request.
if (!this._checkInDialogRequest(request)) {
return;
} // ACK received. Cleanup this._ack_seqnum.
if (request.method === SimpleSIP_C.ACK && this._ack_seqnum !== null) {
this._ack_seqnum = null;
} // INVITE received. Set this._ack_seqnum.
else if (request.method === SimpleSIP_C.INVITE) {
this._ack_seqnum = request.cseq;
}
this._owner.receiveRequest(request);
} // RFC 3261 12.2.1.1.
}, {
key: "_createRequest",
value: function _createRequest(method, extraHeaders, body) {
extraHeaders = Utils.cloneArray(extraHeaders);
if (!this._local_seqnum) {
this._local_seqnum = Math.floor(Math.random() * 10000);
}
var cseq = method === SimpleSIP_C.CANCEL || method === SimpleSIP_C.ACK ? this._local_seqnum : this._local_seqnum += 1;
var request = new SIPMessage.OutgoingRequest(method, this._remote_target, this._ua, {
'cseq': cseq,
'call_id': this._id.call_id,
'from_uri': this._local_uri,
'from_tag': this._id.local_tag,
'to_uri': this._remote_uri,
'to_tag': this._id.remote_tag,
'route_set': this._route_set
}, extraHeaders, body);
return request;
} // RFC 3261 12.2.2.
}, {
key: "_checkInDialogRequest",
value: function _checkInDialogRequest(request) {
var _this2 = this;
if (!this._remote_seqnum) {
this._remote_seqnum = request.cseq;
} else if (request.cseq < this._remote_seqnum) {
if (request.method === SimpleSIP_C.ACK) {
// We are not expecting any ACK with lower seqnum than the current one.
// Or this is not the ACK we are waiting for.
if (this._ack_seqnum === null || request.cseq !== this._ack_seqnum) {
return false;
}
} else {
request.reply(500);
return false;
}
} else if (request.cseq > this._remote_seqnum) {
this._remote_seqnum = request.cseq;
} // RFC3261 14.2 Modifying an Existing Session -UAS BEHAVIOR-.
if (request.method === SimpleSIP_C.INVITE || request.method === SimpleSIP_C.UPDATE && request.body) {
if (this._uac_pending_reply === true) {
request.reply(491);
} else if (this._uas_pending_reply === true) {
var retryAfter = (Math.random() * 10 | 0) + 1;
request.reply(500, null, ["Retry-After:".concat(retryAfter)]);
return false;
} else {
this._uas_pending_reply = true;
var stateChanged = function stateChanged() {
if (request.server_transaction.state === Transactions.C.STATUS_ACCEPTED || request.server_transaction.state === Transactions.C.STATUS_COMPLETED || request.server_transaction.state === Transactions.C.STATUS_TERMINATED) {
request.server_transaction.removeListener('stateChanged', stateChanged);
_this2._uas_pending_reply = false;
}
};
request.server_transaction.on('stateChanged', stateChanged);
} // RFC3261 12.2.2 Replace the dialog`s remote target URI if the request is accepted.
if (request.hasHeader('contact')) {
request.server_transaction.on('stateChanged', function () {
if (request.server_transaction.state === Transactions.C.STATUS_ACCEPTED) {
_this2._remote_target = request.parseHeader('contact').uri;
}
});
}
} else if (request.method === SimpleSIP_C.NOTIFY) {
// RFC6665 3.2 Replace the dialog`s remote target URI if the request is accepted.
if (request.hasHeader('contact')) {
request.server_transaction.on('stateChanged', function () {
if (request.server_transaction.state === Transactions.C.STATUS_COMPLETED) {
_this2._remote_target = request.parseHeader('contact').uri;
}
});
}
}
return true;
}
}, {
key: "id",
get: function get() {
return this._id;
}
}, {
key: "local_seqnum",
get: function get() {
return this._local_seqnum;
},
set: function set(num) {
this._local_seqnum = num;
}
}, {
key: "owner",
get: function get() {
return this._owner;
}
}, {
key: "uac_pending_reply",
get: function get() {
return this._uac_pending_reply;
},
set: function set(pending) {
this._uac_pending_reply = pending;
}
}, {
key: "uas_pending_reply",
get: function get() {
return this._uas_pending_reply;
}
}]);
return Dialog;
}();
},{"./Constants":2,"./Dialog/RequestSender":4,"./Logger":9,"./SIPMessage":21,"./Transactions":24,"./Utils":28}],4:[function(require,module,exports){
"use strict";
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }
var SimpleSIP_C = require('../Constants');
var Transactions = require('../Transactions');
var RequestSender = require('../RequestSender'); // Default event handlers.
var EventHandlers = {
onRequestTimeout: function onRequestTimeout() {},
onTransportError: function onTransportError() {},
onSuccessResponse: function onSuccessResponse() {},
onErrorResponse: function onErrorResponse() {},
onAuthenticated: function onAuthenticated() {},
onDialogError: function onDialogError() {}
};
module.exports = /*#__PURE__*/function () {
function DialogRequestSender(dialog, request, eventHandlers) {
_classCallCheck(this, DialogRequestSender);
this._dialog = dialog;
this._ua = dialog._ua;
this._request = request;
this._eventHandlers = eventHandlers; // RFC3261 14.1 Modifying an Existing Session. UAC Behavior.
this._reattempt = false;
this._reattemptTimer = null; // Define the undefined handlers.
for (var handler in EventHandlers) {
if (Object.prototype.hasOwnProperty.call(EventHandlers, handler)) {
if (!this._eventHandlers[handler]) {
this._eventHandlers[handler] = EventHandlers[handler];
}
}
}
}
_createClass(DialogRequestSender, [{
key: "send",
value: function send() {
var _this = this;
var request_sender = new RequestSender(this._ua, this._request, {
onRequestTimeout: function onRequestTimeout() {
_this._eventHandlers.onRequestTimeout();
},
onTransportError: function onTransportError() {
_this._eventHandlers.onTransportError();
},
onAuthenticated: function onAuthenticated(request) {
_this._eventHandlers.onAuthenticated(request);
},
onReceiveResponse: function onReceiveResponse(response) {
_this._receiveResponse(response);
}
});
request_sender.send(); // RFC3261 14.2 Modifying an Existing Session -UAC BEHAVIOR-.
if ((this._request.method === SimpleSIP_C.INVITE || this._request.method === SimpleSIP_C.UPDATE && this._request.body) && request_sender.clientTransaction.state !== Transactions.C.STATUS_TERMINATED) {
this._dialog.uac_pending_reply = true;
var stateChanged = function stateChanged() {
if (request_sender.clientTransaction.state === Transactions.C.STATUS_ACCEPTED || request_sender.clientTransaction.state === Transactions.C.STATUS_COMPLETED || request_sender.clientTransaction.state === Transactions.C.STATUS_TERMINATED) {
request_sender.clientTransaction.removeListener('stateChanged', stateChanged);
_this._dialog.uac_pending_reply = false;
}
};
request_sender.clientTransaction.on('stateChanged', stateChanged);
}
}
}, {
key: "_receiveResponse",
value: function _receiveResponse(response) {
var _this2 = this;
// RFC3261 12.2.1.2 408 or 481 is received for a request within a dialog.
if (response.status_code === 408 || response.status_code === 481) {
this._eventHandlers.onDialogError(response);
} else if (response.method === SimpleSIP_C.INVITE && response.status_code === 491) {
if (this._reattempt) {
if (response.status_code >= 200 && response.status_code < 300) {
this._eventHandlers.onSuccessResponse(response);
} else if (response.status_code >= 300) {
this._eventHandlers.onErrorResponse(response);
}
} else {
this._request.cseq = this._dialog.local_seqnum += 1;
this._reattemptTimer = setTimeout(function () {
if (!_this2._dialog.isTerminated()) {
_this2._reattempt = true;
_this2.send();
}
}, 1000);
}
} else if (response.status_code >= 200 && response.status_code < 300) {
this._eventHandlers.onSuccessResponse(response);
} else if (response.status_code >= 300) {
this._eventHandlers.onErrorResponse(response);
}
}
}, {
key: "request",
get: function get() {
return this._request;
}
}]);
return DialogRequestSender;
}();
},{"../Constants":2,"../RequestSender":20,"../Transactions":24}],5:[function(require,module,exports){
"use strict";
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }
var Logger = require('./Logger');
var Utils = require('./Utils');
var logger = new Logger('DigestAuthentication');
module.exports = /*#__PURE__*/function () {
function DigestAuthentication(credentials) {
_classCallCheck(this, DigestAuthentication);
this._credentials = credentials;
this._cnonce = null;
this._nc = 0;
this._ncHex = '00000000';
this._algorithm = null;
this._realm = null;
this._nonce = null;
this._opaque = null;
this._stale = null;
this._qop = null;
this._method = null;
this._uri = null;
this._ha1 = null;
this._response = null;
}
_createClass(DigestAuthentication, [{
key: "get",
value: function get(parameter) {
switch (parameter) {
case 'realm':
return this._realm;
case 'ha1':
return this._ha1;
default:
logger.warn('get() | cannot get "%s" parameter', parameter);
return undefined;
}
}
/**
* Performs Digest authentication given a SIP request and the challenge
* received in a response to that request.
* Returns true if auth was successfully generated, false otherwise.
*/
}, {
key: "authenticate",
value: function authenticate(_ref, challenge)
/* test interface */
{
var method = _ref.method,
ruri = _ref.ruri,
body = _ref.body;
var cnonce = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null;
this._algorithm = challenge.algorithm;
this._realm = challenge.realm;
this._nonce = challenge.nonce;
this._opaque = challenge.opaque;
this._stale = challenge.stale;
if (this._algorithm) {
if (this._algorithm !== 'MD5') {
logger.warn('authenticate() | challenge with Digest algorithm different than "MD5", authentication aborted');
return false;
}
} else {
this._algorithm = 'MD5';
}
if (!this._nonce) {
logger.warn('authenticate() | challenge without Digest nonce, authentication aborted');
return false;
}
if (!this._realm) {
logger.warn('authenticate() | challenge without Digest realm, authentication aborted');
return false;
} // If no plain SIP password is provided.
if (!this._credentials.password) {
// If ha1 is not provided we cannot authenticate.
if (!this._credentials.ha1) {
logger.warn('authenticate() | no plain SIP password nor ha1 provided, authentication aborted');
return false;
} // If the realm does not match the stored realm we cannot authenticate.
if (this._credentials.realm !== this._realm) {
logger.warn('authenticate() | no plain SIP password, and stored `realm` does not match the given `realm`, cannot authenticate [stored:"%s", given:"%s"]', this._credentials.realm, this._realm);
return false;
}
} // 'qop' can contain a list of values (Array). Let's choose just one.
if (challenge.qop) {
if (challenge.qop.indexOf('auth-int') > -1) {
this._qop = 'auth-int';
} else if (challenge.qop.indexOf('auth') > -1) {
this._qop = 'auth';
} else {
// Otherwise 'qop' is present but does not contain 'auth' or 'auth-int', so abort here.
logger.warn('authenticate() | challenge without Digest qop different than "auth" or "auth-int", authentication aborted');
return false;
}
} else {
this._qop = null;
} // Fill other attributes.
this._method = method;
this._uri = ruri;
this._cnonce = cnonce || Utils.createRandomToken(12);
this._nc += 1;
var hex = Number(this._nc).toString(16);
this._ncHex = '00000000'.substr(0, 8 - hex.length) + hex; // Nc-value = 8LHEX. Max value = 'FFFFFFFF'.
if (this._nc === 4294967296) {
this._nc = 1;
this._ncHex = '00000001';
} // Calculate the Digest "response" value.
// If we have plain SIP password then regenerate ha1.
if (this._credentials.password) {
// HA1 = MD5(A1) = MD5(username:realm:password).
this._ha1 = Utils.calculateMD5("".concat(this._credentials.username, ":").concat(this._realm, ":").concat(this._credentials.password));
} // Otherwise reuse the stored ha1.
else {
this._ha1 = this._credentials.ha1;
}
var a2;
var ha2;
if (this._qop === 'auth') {
// HA2 = MD5(A2) = MD5(method:digestURI).
a2 = "".concat(this._method, ":").concat(this._uri);
ha2 = Utils.calculateMD5(a2);
logger.debug('authenticate() | using qop=auth [a2:"%s"]', a2); // Response = MD5(HA1:nonce:nonceCount:credentialsNonce:qop:HA2).
this._response = Utils.calculateMD5("".concat(this._ha1, ":").concat(this._nonce, ":").concat(this._ncHex, ":").concat(this._cnonce, ":auth:").concat(ha2));
} else if (this._qop === 'auth-int') {
// HA2 = MD5(A2) = MD5(method:digestURI:MD5(entityBody)).
a2 = "".concat(this._method, ":").concat(this._uri, ":").concat(Utils.calculateMD5(body ? body : ''));
ha2 = Utils.calculateMD5(a2);
logger.debug('authenticate() | using qop=auth-int [a2:"%s"]', a2); // Response = MD5(HA1:nonce:nonceCount:credentialsNonce:qop:HA2).
this._response = Utils.calculateMD5("".concat(this._ha1, ":").concat(this._nonce, ":").concat(this._ncHex, ":").concat(this._cnonce, ":auth-int:").concat(ha2));
} else if (this._qop === null) {
// HA2 = MD5(A2) = MD5(method:digestURI).
a2 = "".concat(this._method, ":").concat(this._uri);
ha2 = Utils.calculateMD5(a2);
logger.debug('authenticate() | using qop=null [a2:"%s"]', a2); // Response = MD5(HA1:nonce:HA2).
this._response = Utils.calculateMD5("".concat(this._ha1, ":").concat(this._nonce, ":").concat(ha2));
}
logger.debug('authenticate() | response generated');
return true;
}
/**
* Return the Proxy-Authorization or WWW-Authorization header value.
*/
}, {
key: "toString",
value: function toString() {
var auth_params = [];
if (!this._response) {
throw new Error('response field does not exist, cannot generate Authorization header');
}
auth_params.push("algorithm=".concat(this._algorithm));
auth_params.push("username=\"".concat(this._credentials.username, "\""));
auth_params.push("realm=\"".concat(this._realm, "\""));
auth_params.push("nonce=\"".concat(this._nonce, "\""));
auth_params.push("uri=\"".concat(this._uri, "\""));
auth_params.push("response=\"".concat(this._response, "\""));
if (this._opaque) {
auth_params.push("opaque=\"".concat(this._opaque, "\""));
}
if (this._qop) {
auth_params.push("qop=".concat(this._qop));
auth_params.push("cnonce=\"".concat(this._cnonce, "\""));
auth_params.push("nc=".concat(this._ncHex));
}
return "Digest ".concat(auth_params.join(', '));
}
}]);
return DigestAuthentication;
}();
},{"./Logger":9,"./Utils":28}],6:[function(require,module,exports){
"use strict";
function _typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); if (superClass) _setPrototypeOf(subClass, superClass); }
function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; }
function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === "object" || typeof call === "function")) { return call; } return _assertThisInitialized(self); }
function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; }
function _wrapNativeSuper(Class) { var _cache = typeof Map === "function" ? new Map() : undefined; _wrapNativeSuper = function _wrapNativeSuper(Class) { if (Class === null || !_isNativeFunction(Class)) return Class; if (typeof Class !== "function") { throw new TypeError("Super expression must either be null or a function"); } if (typeof _cache !== "undefined") { if (_cache.has(Class)) return _cache.get(Class); _cache.set(Class, Wrapper); } function Wrapper() { return _construct(Class, arguments, _getPrototypeOf(this).constructor); } Wrapper.prototype = Object.create(Class.prototype, { constructor: { value: Wrapper, enumerable: false, writable: true, configurable: true } }); return _setPrototypeOf(Wrapper, Class); }; return _wrapNativeSuper(Class); }
function _construct(Parent, args, Class) { if (_isNativeReflectConstruct()) { _construct = Reflect.construct; } else { _construct = function _construct(Parent, args, Class) { var a = [null]; a.push.apply(a, args); var Constructor = Function.bind.apply(Parent, a); var instance = new Constructor(); if (Class) _setPrototypeOf(instance, Class.prototype); return instance; }; } return _construct.apply(null, arguments); }
function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); return true; } catch (e) { return false; } }
function _isNativeFunction(fn) { return Function.toString.call(fn).indexOf("[native code]") !== -1; }
function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }
function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }
var ConfigurationError = /*#__PURE__*/function (_Error) {
_inherits(ConfigurationError, _Error);
var _super = _createSuper(ConfigurationError);
function ConfigurationError(parameter, value) {
var _this;
_classCallCheck(this, ConfigurationError);
_this = _super.call(this);
_this.code = 1;
_this.name = 'CONFIGURATION_ERROR';
_this.parameter = parameter;
_this.value = value;
_this.message = !_this.value ? "Missing parameter: ".concat(_this.parameter) : "Invalid value ".concat(JSON.stringify(_this.value), " for parameter \"").concat(_this.parameter, "\"");
return _this;
}
return ConfigurationError;
}( /*#__PURE__*/_wrapNativeSuper(Error));
var InvalidStateError = /*#__PURE__*/function (_Error2) {
_inherits(InvalidStateError, _Error2);
var _super2 = _createSuper(InvalidStateError);
function InvalidStateError(status) {
var _this2;
_classCallCheck(this, InvalidStateError);
_this2 = _super2.call(this);
_this2.code = 2;
_this2.name = 'INVALID_STATE_ERROR';
_this2.status = status;
_this2.message = "Invalid status: ".concat(status);
return _this2;
}
return InvalidStateError;
}( /*#__PURE__*/_wrapNativeSuper(Error));
var NotSupportedError = /*#__PURE__*/function (_Error3) {
_inherits(NotSupportedError, _Error3);
var _super3 = _createSuper(NotSupportedError);
function NotSupportedError(message) {
var _this3;
_classCallCheck(this, NotSupportedError);
_this3 = _super3.call(this);
_this3.code = 3;
_this3.name = 'NOT_SUPPORTED_ERROR';
_this3.message = message;
return _this3;
}
return NotSupportedError;
}( /*#__PURE__*/_wrapNativeSuper(Error));
var NotReadyError = /*#__PURE__*/function (_Error4) {
_inherits(NotReadyError, _Error4);
var _super4 = _createSuper(NotReadyError);
function NotReadyError(message) {
var _this4;
_classCallCheck(this, NotReadyError);
_this4 = _super4.call(this);
_this4.code = 4;
_this4.name = 'NOT_READY_ERROR';
_this4.message = message;
return _this4;
}
return NotReadyError;
}( /*#__PURE__*/_wrapNativeSuper(Error));
module.exports = {
ConfigurationError: ConfigurationError,
InvalidStateError: InvalidStateError,
NotSupportedError: NotSupportedError,
NotReadyError: NotReadyError
};
},{}],7:[function(require,module,exports){
"use strict";
module.exports = function () {
/*
* Generated by PEG.js 0.7.0.
*
* http://pegjs.majda.cz/
*/
function quote(s) {
/*
* ECMA-262, 5th ed., 7.8.4: All characters may appear literally in a
* string literal except for the closing quote character, backslash,
* carriage return, line separator, paragraph separator, and line feed.
* Any character may appear in the form of an escape sequence.
*
* For portability, we also escape escape all control and non-ASCII
* characters. Note that "\0" and "\v" escape sequences are not used
* because JSHint does not like the first and IE the second.
*/
return '"' + s.replace(/\\/g, '\\\\') // backslash
.replace(/"/g, '\\"') // closing quote character
.replace(/\x08/g, '\\b') // backspace
.replace(/\t/g, '\\t') // horizontal tab
.replace(/\n/g, '\\n') // line feed
.replace(/\f/g, '\\f') // form feed
.replace(/\r/g, '\\r') // carriage return
.replace(/[\x00-\x07\x0B\x0E-\x1F\x80-\uFFFF]/g, escape) + '"';
}
var result = {
/*
* Parses the input with a generated parser. If the parsing is successfull,
* returns a value explicitly or implicitly specified by the grammar from
* which the parser was generated (see |PEG.buildParser|). If the parsing is
* unsuccessful, throws |PEG.parser.SyntaxError| describing the error.
*/
parse: function parse(input, startRule) {
var parseFunctions = {
"CRLF": parse_CRLF,
"DIGIT": parse_DIGIT,
"ALPHA": parse_ALPHA,
"HEXDIG": parse_HEXDIG,
"WSP": parse_WSP,
"OCTET": parse_OCTET,
"DQUOTE": parse_DQUOTE,
"SP": parse_SP,
"HTAB": parse_HTAB,
"alphanum": parse_alphanum,
"reserved": parse_reserved,
"unreserved": parse_unreserved,
"mark": parse_mark,
"escaped": parse_escaped,
"LWS": parse_LWS,
"SWS": parse_SWS,
"HCOLON": parse_HCOLON,
"TEXT_UTF8_TRIM": parse_TEXT_UTF8_TRIM,
"TEXT_UTF8char": parse_TEXT_UTF8char,
"UTF8_NONASCII": parse_UTF8_NONASCII,
"UTF8_CONT": parse_UTF8_CONT,
"LHEX": parse_LHEX,
"token": parse_token,
"token_nodot": parse_token_nodot,
"separators": parse_separators,
"word": parse_word,
"STAR": parse_STAR,
"SLASH": parse_SLASH,
"EQUAL": parse_EQUAL,
"LPAREN": parse_LPAREN,
"RPAREN": parse_RPAREN,
"RAQUOT": parse_RAQUOT,
"LAQUOT": parse_LAQUOT,
"COMMA": parse_COMMA,
"SEMI": parse_SEMI,
"COLON": parse_COLON,
"LDQUOT": parse_LDQUOT,
"RDQUOT": parse_RDQUOT,
"comment": parse_comment,
"ctext": parse_ctext,
"quoted_string": parse_quoted_string,
"quoted_string_clean": parse_quoted_string_clean,
"qdtext": parse_qdtext,
"quoted_pair": parse_quoted_pair,
"SIP_URI_noparams": parse_SIP_URI_noparams,
"SIP_URI": parse_SIP_URI,
"uri_scheme": parse_uri_scheme,
"uri_scheme_sips": parse_uri_scheme_sips,
"uri_scheme_sip": parse_uri_scheme_sip,
"userinfo": parse_userinfo,
"user": parse_user,
"user_unreserved": parse_user_unreserved,
"password": parse_password,
"hostport": parse_hostport,
"host": parse_host,
"hostname": parse_hostname,
"domainlabel": parse_domainlabel,
"toplabel": parse_toplabel,
"IPv6reference": parse_IPv6reference,
"IPv6address": parse_IPv6address,
"h16": parse_h16,
"ls32": parse_ls32,
"IPv4address": parse_IPv4address,
"dec_octet": parse_dec_octet,
"port": parse_port,
"uri_parameters": parse_uri_parameters,
"uri_parameter": parse_uri_parameter,
"transport_param": parse_transport_param,
"user_param": parse_user_param,
"method_param": parse_method_param,
"ttl_param": parse_ttl_param,
"maddr_param": parse_maddr_param,
"lr_param": parse_lr_param,
"other_param": parse_other_param,
"pname": parse_pname,
"pvalue": parse_pvalue,
"paramchar": parse_paramchar,
"param_unreserved": parse_param_unreserved,
"headers": parse_headers,
"header": parse_header,
"hname": parse_hname,
"hvalue": parse_hvalue,
"hnv_unreserved": parse_hnv_unreserved,
"Request_Response": parse_Request_Response,
"Request_Line": parse_Request_Line,
"Request_URI": parse_Request_URI,
"absoluteURI": parse_absoluteURI,
"hier_part": parse_hier_part,
"net_path": parse_net_path,
"abs_path": parse_abs_path,
"opaque_part": parse_opaque_part,
"uric": parse_uric,
"uric_no_slash": parse_uric_no_slash,
"path_segments": parse_path_segments,
"segment": parse_segment,
"param": parse_param,
"pchar": parse_pchar,
"scheme": parse_scheme,
"authority": parse_authority,
"srvr": parse_srvr,
"reg_name": parse_reg_name,
"query": parse_query,
"SIP_Version": parse_SIP_Version,
"INVITEm": parse_INVITEm,
"ACKm": parse_ACKm,
"OPTIONSm": parse_OPTIONSm,
"BYEm": parse_BYEm,
"CANCELm": parse_CANCELm,
"REGISTERm": parse_REGISTERm,
"SUBSCRIBEm": parse_SUBSCRIBEm,
"NOTIFYm": parse_NOTIFYm,
"REFERm": parse_REFERm,
"Method": parse_Method,
"Status_Line": parse_Status_Line,
"Status_Code": parse_Status_Code,
"extension_code": parse_extension_code,
"Reason_Phrase": parse_Reason_Phrase,
"Allow_Events": parse_Allow_Events,
"Call_ID": parse_Call_ID,
"Contact": parse_Contact,
"contact_param": parse_contact_param,
"name_addr": parse_name_addr,
"display_name": parse_display_name,
"contact_params": parse_contact_params,
"c_p_q": parse_c_p_q,
"c_p_expires": parse_c_p_expires,
"delta_seconds": parse_delta_seconds,
"qvalue": parse_qvalue,
"generic_param": parse_generic_param,
"gen_value": parse_gen_value,
"Content_Disposition": parse_Content_Disposition,
"disp_type": parse_disp_type,
"disp_param": parse_disp_param,
"handling_param": parse_handling_param,
"Content_Encoding": parse_Content_Encoding,
"Content_Length": parse_Content_Length,
"Content_Type": parse_Content_Type,
"media_type": parse_media_type,
"m_type": parse_m_type,
"discrete_type": parse_discrete_type,
"composite_type": parse_composite_type,
"extension_token": parse_extension_token,
"x_token": parse_x_token,
"m_subtype": parse_m_subtype,
"m_parameter": parse_m_parameter,
"m_value": parse_m_value,
"CSeq": parse_CSeq,
"CSeq_value": parse_CSeq_value,
"Expires": parse_Expires,
"Event": parse_Event,
"event_type": parse_event_type,
"From": parse_From,
"from_param": parse_from_param,
"tag_param": parse_tag_param,
"Max_Forwards": parse_Max_Forwards,
"Min_Expires": parse_Min_Expires,
"Name_Addr_Header": parse_Name_Addr_Header,
"Proxy_Authenticate": parse_Proxy_Authenticate,
"challenge": parse_challenge,
"other_challenge": parse_other_challenge,
"auth_param": parse_auth_param,
"digest_cln": parse_digest_cln,
"realm": parse_realm,
"realm_value": parse_realm_value,
"domain": parse_domain,
"URI": parse_URI,
"nonce": parse_nonce,
"nonce_value": parse_nonce_value,
"opaque": parse_opaque,
"stale": parse_stale,
"algorithm": parse_algorithm,
"qop_options": parse_qop_options,
"qop_value": parse_qop_value,
"Proxy_Require": parse_Proxy_Require,
"Record_Route": parse_Record_Route,
"rec_route": parse_rec_route,
"Reason": parse_Reason,
"reason_param": parse_reason_param,
"reason_cause": parse_reason_cause,
"Require": parse_Require,
"Route": parse_Route,
"route_param": parse_route_param,
"Subscription_State": parse_Subscription_State,
"substate_value": parse_substate_value,
"subexp_params": parse_subexp_params,
"event_reason_value": parse_event_reason_value,
"Subject": parse_Subject,
"Supported": parse_Supported,
"To": parse_To,
"to_param": parse_to_param,
"Via": parse_Via,
"via_param": parse_via_param,
"via_params": parse_via_params,
"via_ttl": parse_via_ttl,
"via_maddr": parse_via_maddr,
"via_received": parse_via_received,
"via_branch": parse_via_branch,
"response_port": parse_response_port,
"rport": parse_rport,
"sent_protocol": parse_sent_protocol,
"protocol_name": parse_protocol_name,
"transport": parse_transport,
"sent_by": parse_sent_by,
"via_host": parse_via_host,
"via_port": parse_via_port,
"ttl": parse_ttl,
"WWW_Authenticate": parse_WWW_Authenticate,
"Session_Expires": parse_Session_Expires,
"s_e_expires": parse_s_e_expires,
"s_e_params": parse_s_e_params,
"s_e_refresher": parse_s_e_refresher,
"extension_header": parse_extension_header,
"header_value": parse_header_value,
"message_body": parse_message_body,
"uuid_URI": parse_uuid_URI,
"uuid": parse_uuid,
"hex4": parse_hex4,
"hex8": parse_hex8,
"hex12": parse_hex12,
"Refer_To": parse_Refer_To,
"Replaces": parse_Replaces,
"call_id": parse_call_id,
"replaces_param": parse_replaces_param,
"to_tag": parse_to_tag,
"from_tag": parse_from_tag,
"early_flag": parse_early_flag
};
if (startRule !== undefined) {
if (parseFunctions[startRule] === undefined) {
throw new Error("Invalid rule name: " + quote(startRule) + ".");
}
} else {
startRule = "CRLF";
}
var pos = 0;
var reportFailures = 0;
var rightmostFailuresPos = 0;
var rightmostFailuresExpected = [];
function padLeft(input, padding, length) {
var result = input;
var padLength = length - input.length;
for (var i = 0; i < padLength; i++) {
result = padding + result;
}
return result;
}
function escape(ch) {
var charCode = ch.charCodeAt(0);
var escapeChar;
var length;
if (charCode <= 0xFF) {
escapeChar = 'x';
length = 2;
} else {
escapeChar = 'u';
length = 4;
}
return '\\' + escapeChar + padLeft(charCode.toString(16).toUpperCase(), '0', length);
}
function matchFailed(failure) {
if (pos < rightmostFailuresPos) {
return;
}
if (pos > rightmostFailuresPos) {
rightmostFailuresPos = pos;
rightmostFailuresExpected = [];
}
rightmostFailuresExpected.push(failure);
}
function parse_CRLF() {
var result0;
if (input.substr(pos, 2) === "\r\n") {
result0 = "\r\n";
pos += 2;
} else {
result0 = null;
if (reportFailures === 0) {
matchFailed("\"\\r\\n\"");
}
}
return result0;
}
function parse_DIGIT() {
var result0;
if (/^[0-9]/.test(input.charAt(pos))) {
result0 = input.charAt(pos);
pos++;
} else {
result0 = null;
if (reportFailures === 0) {
matchFailed("[0-9]");
}
}
return result0;
}
function parse_ALPHA() {
var result0;
if (/^[a-zA-Z]/.test(input.charAt(pos))) {
result0 = input.charAt(pos);
pos++;
} else {
result0 = null;
if (reportFailures === 0) {
matchFailed("[a-zA-Z]");
}
}
return result0;
}
function parse_HEXDIG() {
var result0;
if (/^[0-9a-fA-F]/.test(input.charAt(pos))) {
result0 = input.charAt(pos);
pos++;
} else {
result0 = null;
if (reportFailures === 0) {
matchFailed("[0-9a-fA-F]");
}
}
return result0;
}
function parse_WSP() {
var result0;
result0 = parse_SP();
if (result0 === null) {
result0 = parse_HTAB();
}
return result0;
}
function parse_OCTET() {
var result0;
if (/^[\0-\xFF]/.test(input.charAt(pos))) {
result0 = input.charAt(pos);
pos++;
} else {
result0 = null;
if (reportFailures === 0) {
matchFailed("[\\0-\\xFF]");
}
}
return result0;
}
function parse_DQUOTE() {
var result0;
if (/^["]/.test(input.charAt(pos))) {
result0 = input.charAt(pos);
pos++;
} else {
result0 = null;
if (reportFailures === 0) {
matchFailed("[\"]");
}
}
return result0;
}
function parse_SP() {
var result0;
if (input.charCodeAt(pos) === 32) {
result0 = " ";
pos++;
} else {
result0 = null;
if (reportFailures === 0) {
matchFailed("\" \"");
}
}
return result0;
}
function parse_HTAB() {
var result0;
if (input.charCodeAt(pos) === 9) {
result0 = "\t";
pos++;
} else {
result0 = null;
if (reportFailures === 0) {
matchFailed("\"\\t\"");
}
}
return result0;
}
function parse_alphanum() {
var result0;
if (/^[a-zA-Z0-9]/.test(input.charAt(pos))) {
result0 = input.charAt(pos);
pos++;
} else {
result0 = null;
if (reportFailures === 0) {
matchFailed("[a-zA-Z0-9]");
}
}
return result0;
}
function parse_reserved() {
var result0;
if (input.charCodeAt(pos) === 59) {
result0 = ";";
pos++;
} else {
result0 = null;
if (reportFailures === 0) {
matchFailed("\";\"");
}
}
if (result0 === null) {
if (input.charCodeAt(pos) === 47) {
result0 = "/";
pos++;
} else {
result0 = null;
if (reportFailures === 0) {
matchFailed("\"/\"");
}
}
if (result0 === null) {
if (input.charCodeAt(pos) === 63) {
result0 = "?";
pos++;
} else {
result0 = null;
if (reportFailures === 0) {
matchFailed("\"?\"");
}
}
if (result0 === null) {
if (input.charCodeAt(pos) === 58) {
result0 = ":";
pos++;
} else {
result0 = null;
if (reportFailures === 0) {
matchFailed("\":\"");
}
}
if (result0 === null) {
if (input.charCodeAt(pos) === 64) {
result0 = "@";
pos++;
} else {
result0 = null;
if (reportFailures === 0) {
matchFailed("\"@\"");
}
}
if (result0 === null) {
if (input.charCodeAt(pos) === 38) {
result0 = "&";
pos++;
} else {
result0 = null;
if (reportFailures === 0) {
matchFailed("\"&\"");
}
}
if (result0 === null) {
if (input.charCodeAt(pos) === 61) {
result0 = "=";
pos++;
} else {
result0 = null;
if (reportFailures === 0) {
matchFailed("\"=\"");
}
}
if (result0 === null) {
if (input.charCodeAt(pos) === 43) {
result0 = "+";
pos++;
} else {
result0 = null;
if (reportFailures === 0) {
matchFailed("\"+\"");
}
}
if (result0 === null) {
if (input.charCodeAt(pos) === 36) {
result0 = "$";
pos++;
} else {
result0 = null;
if (reportFailures === 0) {
matchFailed("\"$\"");
}
}
if (result0 === null) {
if (input.charCodeAt(pos) === 44) {
result0 = ",";
pos++;
} else {
result0 = null;
if (reportFailures === 0) {
matchFailed("\",\"");
}
}
}
}
}
}
}
}
}
}
}
return result0;
}
function parse_unreserved() {
var result0;
result0 = parse_alphanum();
if (result0 === null) {
result0 = parse_mark();
}
return result0;
}
function parse_mark() {
var result0;
if (input.charCodeAt(pos) === 45) {
result0 = "-";
pos++;
} else {
result0 = null;
if (reportFailures === 0) {
matchFailed("\"-\"");
}
}
if (result0 === null) {
if (input.charCodeAt(pos) === 95) {
result0 = "_";
pos++;
} else {
result0 = null;
if (reportFailures === 0) {
matchFailed("\"_\"");
}
}
if (result0 === null) {
if (input.charCodeAt(pos) === 46) {
result0 = ".";
pos++;
} else {
result0 = null;
if (reportFailures === 0) {
matchFailed("\".\"");
}
}
if (result0 === null) {
if (input.charCodeAt(pos) === 33) {
result0 = "!";
pos++;
} else {
result0 = null;
if (reportFailures === 0) {
matchFailed("\"!\"");
}
}
if (result0 === null) {
if (input.charCodeAt(pos) === 126) {
result0 = "~";
pos++;
} else {
result0 = null;
if (reportFailures === 0) {
matchFailed("\"~\"");
}
}
if (result0 === null) {
if (input.charCodeAt(pos) === 42) {
result0 = "*";
pos++;
} else {
result0 = null;
if (reportFailures === 0) {
matchFailed("\"*\"");
}
}
if (result0 === null) {
if (input.charCodeAt(pos) === 39) {
result0 = "'";
pos++;
} else {
result0 = null;
if (reportFailures === 0) {
matchFailed("\"'\"");
}
}
if (result0 === null) {
if (input.charCodeAt(pos) === 40) {
result0 = "(";
pos++;
} else {
result0 = null;
if (reportFailures === 0) {
matchFailed("\"(\"");
}
}
if (result0 === null) {
if (input.charCodeAt(pos) === 41) {
result0 = ")";
pos++;
} else {
result0 = null;
if (reportFailures === 0) {
matchFailed("\")\"");
}
}
}
}
}
}
}
}
}
}
return result0;
}
function parse_escaped() {
var result0, result1, result2;
var pos0, pos1;
pos0 = pos;
pos1 = pos;
if (input.charCodeAt(pos) === 37) {
result0 = "%";
pos++;
} else {
result0 = null;
if (reportFailures === 0) {
matchFailed("\"%\"");
}
}
if (result0 !== null) {
result1 = parse_HEXDIG();
if (result1 !== null) {
result2 = parse_HEXDIG();
if (result2 !== null) {
result0 = [result0, result1, result2];
} else {
result0 = null;
pos = pos1;
}
} else {
result0 = null;
pos = pos1;
}
} else {
result0 = null;
pos = pos1;
}
if (result0 !== null) {
result0 = function (offset, escaped) {
return escaped.join('');
}(pos0, result0);
}
if (result0 === null) {
pos = pos0;
}
return result0;
}
function parse_LWS() {
var result0, result1, result2;
var pos0, pos1, pos2;
pos0 = pos;
pos1 = pos;
pos2 = pos;
result0 = [];
result1 = parse_WSP();
while (result1 !== null) {
result0.push(result1);
result1 = parse_WSP();
}
if (result0 !== null) {
result1 = parse_CRLF();
if (result1 !== null) {
result0 = [result0, result1];
} else {
result0 = null;
pos = pos2;
}
} else {
result0 = null;
pos = pos2;
}
result0 = result0 !== null ? result0 : "";
if (result0 !== null) {
result2 = parse_WSP();
if (result2 !== null) {
result1 = [];
while (result2 !== null) {
result1.push(result2);
result2 = parse_WSP();
}
} else {
result1 = null;
}
if (result1 !== null) {
result0 = [result0, result1];
} else {
result0 = null;
pos = pos1;
}
} else {
result0 = null;
pos = pos1;
}
if (result0 !== null) {
result0 = function (offset) {
return " ";
}(pos0);
}
if (result0 === null) {
pos = pos0;
}
return result0;
}
function parse_SWS() {
var result0;
result0 = parse_LWS();
result0 = result0 !== null ? result0 : "";
return result0;
}
function parse_HCOLON() {
var result0, result1, result2;
var pos0, pos1;
pos0 = pos;
pos1 = pos;
result0 = [];
result1 = parse_SP();
if (result1 === null) {
result1 = parse_HTAB();
}
while (result1 !== null) {
result0.push(result1);
result1 = parse_SP();
if (result1 === null) {
result1 = parse_HTAB();
}
}
if (result0 !== null) {
if (input.charCodeAt(pos) === 58) {
result1 = ":";
pos++;
} else {
result1 = null;
if (reportFailures === 0) {
matchFailed("\":\"");
}
}
if (result1 !== null) {
result2 = parse_SWS();
if (result2 !== null) {
result0 = [result0, result1, result2];
} else {
result0 = null;
pos = pos1;
}
} else {
result0 = null;
pos = pos1;
}
} else {
result0 = null;
pos = pos1;
}
if (result0 !== null) {
result0 = function (offset) {
return ':';
}(pos0);
}
if (result0 === null) {
pos = pos0;
}
return result0;
}
function parse_TEXT_UTF8_TRIM() {
var result0, result1, result2, result3;
var pos0, pos1, pos2;
pos0 = pos;
pos1 = pos;
result1 = parse_TEXT_UTF8char();
if (result1 !== null) {
result0 = [];
while (result1 !== null) {
result0.push(result1);
result1 = parse_TEXT_UTF8char();
}
} else {
result0 = null;
}
if (result0 !== null) {
result1 = [];
pos2 = pos;
result2 = [];
result3 = parse_LWS();
while (result3 !== null) {
result2.push(result3);
result3 = parse_LWS();
}
if (result2 !== null) {
result3 = parse_TEXT_UTF8char();
if (result3 !== null) {
result2 = [result2, result3];
} else {
result2 = null;
pos = pos2;
}
} else {
result2 = null;
pos = pos2;
}
while (result2 !== null) {
result1.push(result2);
pos2 = pos;
result2 = [];
result3 = parse_LWS();
while (result3 !== null) {
result2.push(result3);
result3 = parse_LWS();
}
if (result2 !== null) {
result3 = parse_TEXT_UTF8char();
if (result3 !== null) {
result2 = [result2, result3];
} else {
result2 = null;
pos = pos2;
}
} else {
result2 = null;
pos = pos2;
}
}
if (result1 !== null) {
result0 = [result0, result1];
} else {
result0 = null;
pos = pos1;
}
} else {
result0 = null;
pos = pos1;
}
if (result0 !== null) {
result0 = function (offset) {
return input.substring(pos, offset);
}(pos0);
}
if (result0 === null) {
pos = pos0;
}
return result0;
}
function parse_TEXT_UTF8char() {
var result0;
if (/^[!-~]/.test(input.charAt(pos))) {
result0 = input.charAt(pos);
pos++;
} else {
result0 = null;
if (reportFailures === 0) {
matchFailed("[!-~]");
}
}
if (result0 === null) {
result0 = parse_UTF8_NONASCII();
}
return result0;
}
function parse_UTF8_NONASCII() {
var result0;
if (/^[\x80-\uFFFF]/.test(input.charAt(pos))) {
result0 = input.charAt(pos);
pos++;
} else {
result0 = null;
if (reportFailures === 0) {
matchFailed("[\\x80-\\uFFFF]");
}
}
return result0;
}
function parse_UTF8_CONT() {
var result0;
if (/^[\x80-\xBF]/.test(input.charAt(pos))) {
result0 = input.charAt(pos);
pos++;
} else {
result0 = null;
if (reportFailures === 0) {
matchFailed("[\\x80-\\xBF]");
}
}
return result0;
}
function parse_LHEX() {
var result0;
result0 = parse_DIGIT();
if (result0 === null) {
if (/^[a-f]/.test(input.charAt(pos))) {
result0 = input.charAt(pos);
pos++;
} else {
result0 = null;
if (reportFailures === 0) {
matchFailed("[a-f]");
}
}
}
return result0;
}
function parse_token() {
var result0, result1;
var pos0;
pos0 = pos;
result1 = parse_alphanum();
if (result1 === null) {
if (input.charCodeAt(pos) === 45) {
result1 = "-";
pos++;
} else {
result1 = null;
if (reportFailures === 0) {
matchFailed("\"-\"");
}
}
if (result1 === null) {
if (input.charCodeAt(pos) === 46) {
result1 = ".";
pos++;
} else {
result1 = null;
if (reportFailures === 0) {
matchFailed("\".\"");
}
}
if (result1 === null) {
if (input.charCodeAt(pos) === 33) {
result1 = "!";
pos++;
} else {
result1 = null;
if (reportFailures === 0) {
matchFailed("\"!\"");
}
}
if (result1 === null) {
if (input.charCodeAt(pos) === 37) {
result1 = "%";
pos++;
} else {
result1 = null;
if (reportFailures === 0) {
matchFailed("\"%\"");
}
}
if (result1 === null) {
if (input.charCodeAt(pos) === 42) {
result1 = "*";
pos++;
} else {
result1 = null;
if (reportFailures === 0) {
matchFailed("\"*\"");
}
}
if (result1 === null) {
if (input.charCodeAt(pos) === 95) {
result1 = "_";
pos++;
} else {
result1 = null;
if (reportFailures === 0) {
matchFailed("\"_\"");
}
}
if (result1 === null) {
if (input.charCodeAt(pos) === 43) {
result1 = "+";
pos++;
} else {
result1 = null;
if (reportFailures === 0) {
matchFailed("\"+\"");
}
}
if (result1 === null) {
if (input.charCodeAt(pos) === 96) {
result1 = "`";
pos++;
} else {
result1 = null;
if (reportFailures === 0) {
matchFailed("\"`\"");
}
}
if (result1 === null) {
if (input.charCodeAt(pos) === 39) {
result1 = "'";
pos++;
} else {
result1 = null;
if (reportFailures === 0) {
matchFailed("\"'\"");
}
}
if (result1 === null) {
if (input.charCodeAt(pos) === 126) {
result1 = "~";
pos++;
} else {
result1 = null;
if (reportFailures === 0) {
matchFailed("\"~\"");
}
}
}
}
}
}
}
}
}
}
}
}
if (result1 !== null) {
result0 = [];
while (result1 !== null) {
result0.push(result1);
result1 = parse_alphanum();
if (result1 === null) {
if (input.charCodeAt(pos) === 45) {
result1 = "-";
pos++;
} else {
result1 = null;
if (reportFailures === 0) {
matchFailed("\"-\"");
}
}
if (result1 === null) {
if (input.charCodeAt(pos) === 46) {
result1 = ".";
pos++;
} else {
result1 = null;
if (reportFailures === 0) {
matchFailed("\".\"");
}
}
if (result1 === null) {
if (input.charCodeAt(pos) === 33) {
result1 = "!";
pos++;
} else {
result1 = null;
if (reportFailures === 0) {
matchFailed("\"!\"");
}
}
if (result1 === null) {
if (input.charCodeAt(pos) === 37) {
result1 = "%";
pos++;
} else {
result1 = null;
if (reportFailures === 0) {
matchFailed("\"%\"");
}
}
if (result1 === null) {
if (input.charCodeAt(pos) === 42) {
result1 = "*";
pos++;
} else {
result1 = null;
if (reportFailures === 0) {
matchFailed("\"*\"");
}
}
if (result1 === null) {
if (input.charCodeAt(pos) === 95) {
result1 = "_";
pos++;
} else {
result1 = null;
if (reportFailures === 0) {
matchFailed("\"_\"");
}
}
if (result1 === null) {
if (input.charCodeAt(pos) === 43) {
result1 = "+";
pos++;
} else {
result1 = null;
if (reportFailures === 0) {
matchFailed("\"+\"");
}
}
if (result1 === null) {
if (input.charCodeAt(pos) === 96) {
result1 = "`";
pos++;
} else {
result1 = null;
if (reportFailures === 0) {
matchFailed("\"`\"");
}
}
if (result1 === null) {
if (input.charCodeAt(pos) === 39) {
result1 = "'";
pos++;
} else {
result1 = null;
if (reportFailures === 0) {
matchFailed("\"'\"");
}
}
if (result1 === null) {
if (input.charCodeAt(pos) === 126) {
result1 = "~";
pos++;
} else {
result1 = null;
if (reportFailures === 0) {
matchFailed("\"~\"");
}
}
}
}
}
}
}
}
}
}
}
}
}
} else {
result0 = null;
}
if (result0 !== null) {
result0 = function (offset) {
return input.substring(pos, offset);
}(pos0);
}
if (result0 === null) {
pos = pos0;
}
return result0;
}
function parse_token_nodot() {
var result0, result1;
var pos0;
pos0 = pos;
result1 = parse_alphanum();
if (result1 === null) {
if (input.charCodeAt(pos) === 45) {
result1 = "-";
pos++;
} else {
result1 = null;
if (reportFailures === 0) {
matchFailed("\"-\"");
}
}
if (result1 === null) {
if (input.charCodeAt(pos) === 33) {
result1 = "!";
pos++;
} else {
result1 = null;
if (reportFailures === 0) {
matchFailed("\"!\"");
}
}
if (result1 === null) {
if (input.charCodeAt(pos) === 37) {
result1 = "%";
pos++;
} else {
result1 = null;
if (reportFailures === 0) {
matchFailed("\"%\"");
}
}
if (result1 === null) {
if (input.charCodeAt(pos) === 42) {
result1 = "*";
pos++;
} else {
result1 = null;
if (reportFailures === 0) {
matchFailed("\"*\"");
}
}
if (result1 === null) {
if (input.charCodeAt(pos) === 95) {
result1 = "_";
pos++;
} else {
result1 = null;
if (reportFailures === 0) {
matchFailed("\"_\"");
}
}
if (result1 === null) {
if (input.charCodeAt(pos) === 43) {
result1 = "+";
pos++;
} else {
result1 = null;
if (reportFailures === 0) {
matchFailed("\"+\"");
}
}
if (result1 === null) {
if (input.charCodeAt(pos) === 96) {
result1 = "`";
pos++;
} else {
result1 = null;
if (reportFailures === 0) {
matchFailed("\"`\"");
}
}
if (result1 === null) {
if (input.charCodeAt(pos) === 39) {
result1 = "'";
pos++;
} else {
result1 = null;
if (reportFailures === 0) {
matchFailed("\"'\"");
}
}
if (result1 === null) {
if (input.charCodeAt(pos) === 126) {
result1 = "~";
pos++;
} else {
result1 = null;
if (reportFailures === 0) {
matchFailed("\"~\"");
}
}
}
}
}
}
}
}
}
}
}
if (result1 !== null) {
result0 = [];
while (result1 !== null) {
result0.push(result1);
result1 = parse_alphanum();
if (result1 === null) {
if (input.charCodeAt(pos) === 45) {
result1 = "-";
pos++;
} else {
result1 = null;
if (reportFailures === 0) {
matchFailed("\"-\"");
}
}
if (result1 === null) {
if (input.charCodeAt(pos) === 33) {
result1 = "!";
pos++;
} else {
result1 = null;
if (reportFailures === 0) {
matchFailed("\"!\"");
}
}
if (result1 === null) {
if (input.charCodeAt(pos) === 37) {
result1 = "%";
pos++;
} else {
result1 = null;
if (reportFailures === 0) {
matchFailed("\"%\"");
}
}
if (result1 === null) {
if (input.charCodeAt(pos) === 42) {
result1 = "*";
pos++;
} else {
result1 = null;
if (reportFailures === 0) {
matchFailed("\"*\"");
}
}
if (result1 === null) {
if (input.charCodeAt(pos) === 95) {
result1 = "_";
pos++;
} else {
result1 = null;
if (reportFailures === 0) {
matchFailed("\"_\"");
}
}
if (result1 === null) {
if (input.charCodeAt(pos) === 43) {
result1 = "+";
pos++;
} else {
result1 = null;
if (reportFailures === 0) {
matchFailed("\"+\"");
}
}
if (result1 === null) {
if (input.charCodeAt(pos) === 96) {
result1 = "`";
pos++;
} else {
result1 = null;
if (reportFailures === 0) {
matchFailed("\"`\"");
}
}
if (result1 === null) {
if (input.charCodeAt(pos) === 39) {
result1 = "'";
pos++;
} else {
result1 = null;
if (reportFailures === 0) {
matchFailed("\"'\"");
}
}
if (result1 === null) {
if (input.charCodeAt(pos) === 126) {
result1 = "~";
pos++;
} else {
result1 = null;
if (reportFailures === 0) {
matchFailed("\"~\"");
}
}
}
}
}
}
}
}
}
}
}
}
} else {
result0 = null;
}
if (result0 !== null) {
result0 = function (offset) {
return input.substring(pos, offset);
}(pos0);
}
if (result0 === null) {
pos = pos0;
}
return result0;
}
function parse_separators() {
var result0;
if (input.charCodeAt(pos) === 40) {
result0 = "(";
pos++;
} else {
result0 = null;
if (reportFailures === 0) {
matchFailed("\"(\"");
}
}
if (result0 === null) {
if (input.charCodeAt(pos) === 41) {
result0 = ")";
pos++;
} else {
result0 = null;
if (reportFailures === 0) {
matchFailed("\")\"");
}
}
if (result0 === null) {
if (input.charCodeAt(pos) === 60) {
result0 = "<";
pos++;
} else {
result0 = null;
if (reportFailures === 0) {
matchFailed("\"<\"");
}
}
if (result0 === null) {
if (input.charCodeAt(pos) === 62) {
result0 = ">";
pos++;
} else {
result0 = null;
if (reportFailures === 0) {
matchFailed("\">\"");
}
}
if (result0 === null) {
if (input.charCodeAt(pos) === 64) {
result0 = "@";
pos++;
} else {
result0 = null;
if (reportFailures === 0) {
matchFailed("\"@\"");
}
}
if (result0 === null) {
if (input.charCodeAt(pos) === 44) {
result0 = ",";
pos++;
} else {
result0 = null;
if (reportFailures === 0) {
matchFailed("\",\"");
}
}
if (result0 === null) {
if (input.charCodeAt(pos) === 59) {
result0 = ";";
pos++;
} else {
result0 = null;
if (reportFailures === 0) {
matchFailed("\";\"");
}
}
if (result0 === null) {
if (input.charCodeAt(pos) === 58) {
result0 = ":";
pos++;
} else {
result0 = null;
if (reportFailures === 0) {
matchFailed("\":\"");
}
}
if (result0 === null) {
if (input.charCodeAt(pos) === 92) {
result0 = "\\";
pos++;
} else {
result0 = null;
if (reportFailures === 0) {
matchFailed("\"\\\\\"");
}
}
if (result0 === null) {
result0 = parse_DQUOTE();
if (result0 === null) {
if (input.charCodeAt(pos) === 47) {
result0 = "/";
pos++;
} else {
result0 = null;
if (reportFailures === 0) {
matchFailed("\"/\"");
}
}
if (result0 === null) {
if (input.charCodeAt(pos) === 91) {
result0 = "[";
pos++;
} else {
result0 = null;
if (reportFailures === 0) {
matchFailed("\"[\"");
}
}
if (result0 === null) {
if (input.charCodeAt(pos) === 93) {
result0 = "]";
pos++;
} else {
result0 = null;
if (reportFailures === 0) {
matchFailed("\"]\"");
}
}
if (result0 === null) {
if (input.charCodeAt(pos) === 63) {
result0 = "?";
pos++;
} else {
result0 = null;
if (reportFailures === 0) {
matchFailed("\"?\"");
}
}
if (result0 === null) {
if (input.charCodeAt(pos) === 61) {
result0 = "=";
pos++;
} else {
result0 = null;
if (reportFailures === 0) {
matchFailed("\"=\"");
}
}
if (result0 === null) {
if (input.charCodeAt(pos) === 123) {
result0 = "{";
pos++;
} else {
result0 = null;
if (reportFailures === 0) {
matchFailed("\"{\"");
}
}
if (result0 === null) {
if (input.charCodeAt(pos) === 125) {
result0 = "}";
pos++;
} else {
result0 = null;
if (reportFailures === 0) {
matchFailed("\"}\"");
}
}
if (result0 === null) {
result0 = parse_SP();
if (result0 === null) {
result0 = parse_HTAB();
}
}
}
}
}
}
}
}
}
}
}
}
}
}
}
}
}
}
return result0;
}
function parse_word() {
var result0, result1;
var pos0;
pos0 = pos;
result1 = parse_alphanum();
if (result1 === null) {
if (input.charCodeAt(pos) === 45) {
result1 = "-";
pos++;
} else {
result1 = null;
if (reportFailures === 0) {
matchFailed("\"-\"");
}
}
if (result1 === null) {
if (input.charCodeAt(pos) === 46) {
result1 = ".";
pos++;
} else {
result1 = null;
if (reportFailures === 0) {
matchFailed("\".\"");
}
}
if (result1 === null) {
if (input.charCodeAt(pos) === 33) {
result1 = "!";
pos++;
} else {
result1 = null;
if (reportFailures === 0) {
matchFailed("\"!\"");
}
}
if (result1 === null) {
if (input.charCodeAt(pos) === 37) {
result1 = "%";
pos++;
} else {
result1 = null;
if (reportFailures === 0) {
matchFailed("\"%\"");
}
}
if (result1 === null) {
if (input.charCodeAt(pos) === 42) {
result1 = "*";
pos++;
} else {
result1 = null;
if (reportFailures === 0) {
matchFailed("\"*\"");
}
}
if (result1 === null) {
if (input.charCodeAt(pos) === 95) {
result1 = "_";
pos++;
} else {
result1 = null;
if (reportFailures === 0) {
matchFailed("\"_\"");
}
}
if (result1 === null) {
if (input.charCodeAt(pos) === 43) {
result1 = "+";
pos++;
} else {
result1 = null;
if (reportFailures === 0) {
matchFailed("\"+\"");
}
}
if (result1 === null) {
if (input.charCodeAt(pos) === 96) {
result1 = "`";
pos++;
} else {
result1 = null;
if (reportFailures === 0) {
matchFailed("\"`\"");
}
}
if (result1 === null) {
if (input.charCodeAt(pos) === 39) {
result1 = "'";
pos++;
} else {
result1 = null;
if (reportFailures === 0) {
matchFailed("\"'\"");
}
}
if (result1 === null) {
if (input.charCodeAt(pos) === 126) {
result1 = "~";
pos++;
} else {
result1 = null;
if (reportFailures === 0) {
matchFailed("\"~\"");
}
}
if (result1 === null) {
if (input.charCodeAt(pos) === 40) {
result1 = "(";
pos++;
} else {
result1 = null;
if (reportFailures === 0) {
matchFailed("\"(\"");
}
}
if (result1 === null) {
if (input.charCodeAt(pos) === 41) {
result1 = ")";
pos++;
} else {
result1 = null;
if (reportFailures === 0) {
matchFailed("\")\"");
}
}
if (result1 === null) {
if (input.charCodeAt(pos) === 60) {
result1 = "<";
pos++;
} else {
result1 = null;
if (reportFailures === 0) {
matchFailed("\"<\"");
}
}
if (result1 === null) {
if (input.charCodeAt(pos) === 62) {
result1 = ">";
pos++;
} else {
result1 = null;
if (reportFailures === 0) {
matchFailed("\">\"");
}
}
if (result1 === null) {
if (input.charCodeAt(pos) === 58) {
result1 = ":";
pos++;
} else {
result1 = null;
if (reportFailures === 0) {
matchFailed("\":\"");
}
}
if (result1 === null) {
if (input.charCodeAt(pos) === 92) {
result1 = "\\";
pos++;
} else {
result1 = null;
if (reportFailures === 0) {
matchFailed("\"\\\\\"");
}
}
if (result1 === null) {
result1 = parse_DQUOTE();
if (result1 === null) {
if (input.charCodeAt(pos) === 47) {
result1 = "/";
pos++;
} else {
result1 = null;
if (reportFailures === 0) {
matchFailed("\"/\"");
}
}
if (result1 === null) {
if (input.charCodeAt(pos) === 91) {
result1 = "[";
pos++;
} else {
result1 = null;
if (reportFailures === 0) {
matchFailed("\"[\"");
}
}
if (result1 === null) {
if (input.charCodeAt(pos) === 93) {
result1 = "]";
pos++;
} else {
result1 = null;
if (reportFailures === 0) {
matchFailed("\"]\"");
}
}
if (result1 === null) {
if (input.charCodeAt(pos) === 63) {
result1 = "?";
pos++;
} else {
result1 = null;
if (reportFailures === 0) {
matchFailed("\"?\"");
}
}
if (result1 === null) {
if (input.charCodeAt(pos) === 123) {
result1 = "{";
pos++;
} else {
result1 = null;
if (reportFailures === 0) {
matchFailed("\"{\"");
}
}
if (result1 === null) {
if (input.charCodeAt(pos) === 125) {
result1 = "}";
pos++;
} else {
result1 = null;
if (reportFailures === 0) {
matchFailed("\"}\"");
}
}
}
}
}
}
}
}
}
}
}
}
}
}
}
}
}
}
}
}
}
}
}
}
}
if (result1 !== null) {
result0 = [];
while (result1 !== null) {
result0.push(result1);
result1 = parse_alphanum();
if (result1 === null) {
if (input.charCodeAt(pos) === 45) {
result1 = "-";
pos++;
} else {
result1 = null;
if (reportFailures === 0) {
matchFailed("\"-\"");
}
}
if (result1 === null) {
if (input.charCodeAt(pos) === 46) {
result1 = ".";
pos++;
} else {
result1 = null;
if (reportFailures === 0) {
matchFailed("\".\"");
}
}
if (result1 === null) {
if (input.charCodeAt(pos) === 33) {
result1 = "!";
pos++;
} else {
result1 = null;
if (reportFailures === 0) {
matchFailed("\"!\"");
}
}
if (result1 === null) {
if (input.charCodeAt(pos) === 37) {
result1 = "%";
pos++;
} else {
result1 = null;
if (reportFailures === 0) {
matchFailed("\"%\"");
}
}
if (result1 === null) {
if (input.charCodeAt(pos) === 42) {
result1 = "*";
pos++;
} else {
result1 = null;
if (reportFailures === 0) {
matchFailed("\"*\"");
}
}
if (result1 === null) {
if (input.charCodeAt(pos) === 95) {
result1 = "_";
pos++;
} else {
result1 = null;
if (reportFailures === 0) {
matchFailed("\"_\"");
}
}
if (result1 === null) {
if (input.charCodeAt(pos) === 43) {
result1 = "+";
pos++;
} else {
result1 = null;
if (reportFailures === 0) {
matchFailed("\"+\"");
}
}
if (result1 === null) {
if (input.charCodeAt(pos) === 96) {
result1 = "`";
pos++;
} else {
result1 = null;
if (reportFailures === 0) {
matchFailed("\"`\"");
}
}
if (result1 === null) {
if (input.charCodeAt(pos) === 39) {
result1 = "'";
pos++;
} else {
result1 = null;
if (reportFailures === 0) {
matchFailed("\"'\"");
}
}
if (result1 === null) {
if (input.charCodeAt(pos) === 126) {
result1 = "~";
pos++;
} else {
result1 = null;
if (reportFailures === 0) {
matchFailed("\"~\"");
}
}
if (result1 === null) {
if (input.charCodeAt(pos) === 40) {
result1 = "(";
pos++;
} else {
result1 = null;
if (reportFailures === 0) {
matchFailed("\"(\"");
}
}
if (result1 === null) {
if (input.charCodeAt(pos) === 41) {
result1 = ")";
pos++;
} else {
result1 = null;
if (reportFailures === 0) {
matchFailed("\")\"");
}
}
if (result1 === null) {
if (input.charCodeAt(pos) === 60) {
result1 = "<";
pos++;
} else {
result1 = null;
if (reportFailures === 0) {
matchFailed("\"<\"");
}
}
if (result1 === null) {
if (input.charCodeAt(pos) === 62) {
result1 = ">";
pos++;
} else {
result1 = null;
if (reportFailures === 0) {
matchFailed("\">\"");
}
}
if (result1 === null) {
if (input.charCodeAt(pos) === 58) {
result1 = ":";
pos++;
} else {
result1 = null;
if (reportFailures === 0) {
matchFailed("\":\"");
}
}
if (result1 === null) {
if (input.charCodeAt(pos) === 92) {
result1 = "\\";
pos++;
} else {
result1 = null;
if (reportFailures === 0) {
matchFailed("\"\\\\\"");
}
}
if (result1 === null) {
result1 = parse_DQUOTE();
if (result1 === null) {
if (input.charCodeAt(pos) === 47) {
result1 = "/";
pos++;
} else {
result1 = null;
if (reportFailures === 0) {
matchFailed("\"/\"");
}
}
if (result1 === null) {
if (input.charCodeAt(pos) === 91) {
result1 = "[";
pos++;
} else {
result1 = null;
if (reportFailures === 0) {
matchFailed("\"[\"");
}
}
if (result1 === null) {
if (input.charCodeAt(pos) === 93) {
result1 = "]";
pos++;
} else {
result1 = null;
if (reportFailures === 0) {
matchFailed("\"]\"");
}
}
if (result1 === null) {
if (input.charCodeAt(pos) === 63) {
result1 = "?";
pos++;
} else {
result1 = null;
if (reportFailures === 0) {
matchFailed("\"?\"");
}
}
if (result1 === null) {
if (input.charCodeAt(pos) === 123) {
result1 = "{";
pos++;
} else {
result1 = null;
if (reportFailures === 0) {
matchFailed("\"{\"");
}
}
if (result1 === null) {
if (input.charCodeAt(pos) === 125) {
result1 = "}";
pos++;
} else {
result1 = null;
if (reportFailures === 0) {
matchFailed("\"}\"");
}
}
}
}
}
}
}
}
}
}
}
}
}
}
}
}
}
}
}
}
}
}
}
}
}
}
} else {
result0 = null;
}
if (result0 !== null) {
result0 = function (offset) {
return input.substring(pos, offset);
}(pos0);
}
if (result0 === null) {
pos = pos0;
}
return result0;
}
function parse_STAR() {
var result0, result1, result2;
var pos0, pos1;
pos0 = pos;
pos1 = pos;
result0 = parse_SWS();
if (result0 !== null) {
if (input.charCodeAt(pos) === 42) {
result1 = "*";
pos++;
} else {
result1 = null;
if (reportFailures === 0) {
matchFailed("\"*\"");
}
}
if (result1 !== null) {
result2 = parse_SWS();
if (result2 !== null) {
result0 = [result0, result1, result2];
} else {
result0 = null;
pos = pos1;
}
} else {
result0 = null;
pos = pos1;
}
} else {
result0 = null;
pos = pos1;
}
if (result0 !== null) {
result0 = function (offset) {
return "*";
}(pos0);
}
if (result0 === null) {
pos = pos0;
}
return result0;
}
function parse_SLASH() {
var result0, result1, result2;
var pos0, pos1;
pos0 = pos;
pos1 = pos;
result0 = parse_SWS();
if (result0 !== null) {
if (input.charCodeAt(pos) === 47) {
result1 = "/";
pos++;
} else {
result1 = null;
if (reportFailures === 0) {
matchFailed("\"/\"");
}
}
if (result1 !== null) {
result2 = parse_SWS();
if (result2 !== null) {
result0 = [result0, result1, result2];
} else {
result0 = null;
pos = pos1;
}
} else {
result0 = null;
pos = pos1;
}
} else {
result0 = null;
pos = pos1;
}
if (result0 !== null) {
result0 = function (offset) {
return "/";
}(pos0);
}
if (result0 === null) {
pos = pos0;
}
return result0;
}
function parse_EQUAL() {
var result0, result1, result2;
var pos0, pos1;
pos0 = pos;
pos1 = pos;
result0 = parse_SWS();
if (result0 !== null) {
if (input.charCodeAt(pos) === 61) {
result1 = "=";
pos++;
} else {
result1 = null;
if (reportFailures === 0) {
matchFailed("\"=\"");
}
}
if (result1 !== null) {
result2 = parse_SWS();
if (result2 !== null) {
result0 = [result0, result1, result2];
} else {
result0 = null;
pos = pos1;
}
} else {
result0 = null;
pos = pos1;
}
} else {
result0 = null;
pos = pos1;
}
if (result0 !== null) {
result0 = function (offset) {
return "=";
}(pos0);
}
if (result0 === null) {
pos = pos0;
}
return result0;
}
function parse_LPAREN() {
var result0, result1, result2;
var pos0, pos1;
pos0 = pos;
pos1 = pos;
result0 = parse_SWS();
if (result0 !== null) {
if (input.charCodeAt(pos) === 40) {
result1 = "(";
pos++;
} else {
result1 = null;
if (reportFailures === 0) {
matchFailed("\"(\"");
}
}
if (result1 !== null) {
result2 = parse_SWS();
if (result2 !== null) {
result0 = [result0, result1, result2];
} else {
result0 = null;
pos = pos1;
}
} else {
result0 = null;
pos = pos1;
}
} else {
result0 = null;
pos = pos1;
}
if (result0 !== null) {
result0 = function (offset) {
return "(";
}(pos0);
}
if (result0 === null) {
pos = pos0;
}
return result0;
}
function parse_RPAREN() {
var result0, result1, result2;
var pos0, pos1;
pos0 = pos;
pos1 = pos;
result0 = parse_SWS();
if (result0 !== null) {
if (input.charCodeAt(pos) === 41) {
result1 = ")";
pos++;
} else {
result1 = null;
if (reportFailures === 0) {
matchFailed("\")\"");
}
}
if (result1 !== null) {
result2 = parse_SWS();
if (result2 !== null) {
result0 = [result0, result1, result2];
} else {
result0 = null;
pos = pos1;
}
} else {
result0 = null;
pos = pos1;
}
} else {
result0 = null;
pos = pos1;
}
if (result0 !== null) {
result0 = function (offset) {
return ")";
}(pos0);
}
if (result0 === null) {
pos = pos0;
}
return result0;
}
function parse_RAQUOT() {
var result0, result1;
var pos0, pos1;
pos0 = pos;
pos1 = pos;
if (input.charCodeAt(pos) === 62) {
result0 = ">";
pos++;
} else {
result0 = null;
if (reportFailures === 0) {
matchFailed("\">\"");
}
}
if (result0 !== null) {
result1 = parse_SWS();
if (result1 !== null) {
result0 = [result0, result1];
} else {
result0 = null;
pos = pos1;
}
} else {
result0 = null;
pos = pos1;
}
if (result0 !== null) {
result0 = function (offset) {
return ">";
}(pos0);
}
if (result0 === null) {
pos = pos0;
}
return result0;
}
function parse_LAQUOT() {
var result0, result1;
var pos0, pos1;
pos0 = pos;
pos1 = pos;
result0 = parse_SWS();
if (result0 !== null) {
if (input.charCodeAt(pos) === 60) {
result1 = "<";
pos++;
} else {
result1 = null;
if (reportFailures === 0) {
matchFailed("\"<\"");
}
}
if (result1 !== null) {
result0 = [result0, result1];
} else {
result0 = null;
pos = pos1;
}
} else {
result0 = null;
pos = pos1;
}
if (result0 !== null) {
result0 = function (offset) {
return "<";
}(pos0);
}
if (result0 === null) {
pos = pos0;
}
return result0;
}
function parse_COMMA() {
var result0, result1, result2;
var pos0, pos1;
pos0 = pos;
pos1 = pos;
result0 = parse_SWS();
if (result0 !== null) {
if (input.charCodeAt(pos) === 44) {
result1 = ",";
pos++;
} else {
result1 = null;
if (reportFailures === 0) {
matchFailed("\",\"");
}
}
if (result1 !== null) {
result2 = parse_SWS();
if (result2 !== null) {
result0 = [result0, result1, result2];
} else {
result0 = null;
pos = pos1;
}
} else {
result0 = null;
pos = pos1;
}
} else {
result0 = null;
pos = pos1;
}
if (result0 !== null) {
result0 = function (offset) {
return ",";
}(pos0);
}
if (result0 === null) {
pos = pos0;
}
return result0;
}
function parse_SEMI() {
var result0, result1, result2;
var pos0, pos1;
pos0 = pos;
pos1 = pos;
result0 = parse_SWS();
if (result0 !== null) {
if (input.charCodeAt(pos) === 59) {
result1 = ";";
pos++;
} else {
result1 = null;
if (reportFailures === 0) {
matchFailed("\";\"");
}
}
if (result1 !== null) {
result2 = parse_SWS();
if (result2 !== null) {
result0 = [result0, result1, result2];
} else {
result0 = null;
pos = pos1;
}
} else {
result0 = null;
pos = pos1;
}
} else {
result0 = null;
pos = pos1;
}
if (result0 !== null) {
result0 = function (offset) {
return ";";
}(pos0);
}
if (result0 === null) {
pos = pos0;
}
return result0;
}
function parse_COLON() {
var result0, result1, result2;
var pos0, pos1;
pos0 = pos;
pos1 = pos;
result0 = parse_SWS();
if (result0 !== null) {
if (input.charCodeAt(pos) === 58) {
result1 = ":";
pos++;
} else {
result1 = null;
if (reportFailures === 0) {
matchFailed("\":\"");
}
}
if (result1 !== null) {
result2 = parse_SWS();
if (result2 !== null) {
result0 = [result0, result1, result2];
} else {
result0 = null;
pos = pos1;
}
} else {
result0 = null;
pos = pos1;
}
} else {
result0 = null;
pos = pos1;
}
if (result0 !== null) {
result0 = function (offset) {
return ":";
}(pos0);
}
if (result0 === null) {
pos = pos0;
}
return result0;
}
function parse_LDQUOT() {
var result0, result1;
var pos0, pos1;
pos0 = pos;
pos1 = pos;
result0 = parse_SWS();
if (result0 !== null) {
result1 = parse_DQUOTE();
if (result1 !== null) {
result0 = [result0, result1];
} else {
result0 = null;
pos = pos1;
}
} else {
result0 = null;
pos = pos1;
}
if (result0 !== null) {
result0 = function (offset) {
return "\"";
}(pos0);
}
if (result0 === null) {
pos = pos0;
}
return result0;
}
function parse_RDQUOT() {
var result0, result1;
var pos0, pos1;
pos0 = pos;
pos1 = pos;
result0 = parse_DQUOTE();
if (result0 !== null) {
result1 = parse_SWS();
if (result1 !== null) {
result0 = [result0, result1];
} else {
result0 = null;
pos = pos1;
}
} else {
result0 = null;
pos = pos1;
}
if (result0 !== null) {
result0 = function (offset) {
return "\"";
}(pos0);
}
if (result0 === null) {
pos = pos0;
}
return result0;
}
function parse_comment() {
var result0, result1, result2;
var pos0;
pos0 = pos;
result0 = parse_LPAREN();
if (result0 !== null) {
result1 = [];
result2 = parse_ctext();
if (result2 === null) {
result2 = parse_quoted_pair();
if (result2 === null) {
result2 = parse_comment();
}
}
while (result2 !== null) {
result1.push(result2);
result2 = parse_ctext();
if (result2 === null) {
result2 = parse_quoted_pair();
if (result2 === null) {
result2 = parse_comment();
}
}
}
if (result1 !== null) {
result2 = parse_RPAREN();
if (result2 !== null) {
result0 = [result0, result1, result2];
} else {
result0 = null;
pos = pos0;
}
} else {
result0 = null;
pos = pos0;
}
} else {
result0 = null;
pos = pos0;
}
return result0;
}
function parse_ctext() {
var result0;
if (/^[!-']/.test(input.charAt(pos))) {
result0 = input.charAt(pos);
pos++;
} else {
result0 = null;
if (reportFailures === 0) {
matchFailed("[!-']");
}
}
if (result0 === null) {
if (/^[*-[]/.test(input.charAt(pos))) {
result0 = input.charAt(pos);
pos++;
} else {
result0 = null;
if (reportFailures === 0) {
matchFailed("[*-[]");
}
}
if (result0 === null) {
if (/^[\]-~]/.test(input.charAt(pos))) {
result0 = input.charAt(pos);
pos++;
} else {
result0 = null;
if (reportFailures === 0) {
matchFailed("[\\]-~]");
}
}
if (result0 === null) {
result0 = parse_UTF8_NONASCII();
if (result0 === null) {
result0 = parse_LWS();
}
}
}
}
return result0;
}
function parse_quoted_string() {
var result0, result1, result2, result3;
var pos0, pos1;
pos0 = pos;
pos1 = pos;
result0 = parse_SWS();
if (result0 !== null) {
result1 = parse_DQUOTE();
if (result1 !== null) {
result2 = [];
result3 = parse_qdtext();
if (result3 === null) {
result3 = parse_quoted_pair();
}
while (result3 !== null) {
result2.push(result3);
result3 = parse_qdtext();
if (result3 === null) {
result3 = parse_quoted_pair();
}
}
if (result2 !== null) {
result3 = parse_DQUOTE();
if (result3 !== null) {
result0 = [result0, result1, result2, result3];
} else {
result0 = null;
pos = pos1;
}
} else {
result0 = null;
pos = pos1;
}
} else {
result0 = null;
pos = pos1;
}
} else {
result0 = null;
pos = pos1;
}
if (result0 !== null) {
result0 = function (offset) {
return input.substring(pos, offset);
}(pos0);
}
if (result0 === null) {
pos = pos0;
}
return result0;
}
function parse_quoted_string_clean() {
var result0, result1, result2, result3;
var pos0, pos1;
pos0 = pos;
pos1 = pos;
result0 = parse_SWS();
if (result0 !== null) {
result1 = parse_DQUOTE();
if (result1 !== null) {
result2 = [];
result3 = parse_qdtext();
if (result3 === null) {
result3 = parse_quoted_pair();
}
while (result3 !== null) {
result2.push(result3);
result3 = parse_qdtext();
if (result3 === null) {
result3 = parse_quoted_pair();
}
}
if (result2 !== null) {
result3 = parse_DQUOTE();
if (result3 !== null) {
result0 = [result0, result1, result2, result3];
} else {
result0 = null;
pos = pos1;
}
} else {
result0 = null;
pos = pos1;
}
} else {
result0 = null;
pos = pos1;
}
} else {
result0 = null;
pos = pos1;
}
if (result0 !== null) {
result0 = function (offset) {
var trimmed = input.substring(pos, offset).trim();
return trimmed.substring(1, trimmed.length - 1) // remove outer quotes
.replace(/\\([\x00-\x09\x0b-\x0c\x0e-\x7f])/g, '$1');
}(pos0);
}
if (result0 === null) {
pos = pos0;
}
return result0;
}
function parse_qdtext() {
var result0;
result0 = parse_LWS();
if (result0 === null) {
if (input.charCodeAt(pos) === 33) {
result0 = "!";
pos++;
} else {
result0 = null;
if (reportFailures === 0) {
matchFailed("\"!\"");
}
}
if (result0 === null) {
if (/^[#-[]/.test(input.charAt(pos))) {
result0 = input.charAt(pos);
pos++;
} else {
result0 = null;
if (reportFailures === 0) {
matchFailed("[#-[]");
}
}
if (result0 === null) {
if (/^[\]-~]/.test(input.charAt(pos))) {
result0 = input.charAt(pos);
pos++;
} else {
result0 = null;
if (reportFailures === 0) {
matchFailed("[\\]-~]");
}
}
if (result0 === null) {
result0 = parse_UTF8_NONASCII();
}
}
}
}
return result0;
}
function parse_quoted_pair() {
var result0, result1;
var pos0;
pos0 = pos;
if (input.charCodeAt(pos) === 92) {
result0 = "\\";
pos++;
} else {
result0 = null;
if (reportFailures === 0) {
matchFailed("\"\\\\\"");
}
}
if (result0 !== null) {
if (/^[\0-\t]/.test(input.charAt(pos))) {
result1 = input.charAt(pos);
pos++;
} else {
result1 = null;
if (reportFailures === 0) {
matchFailed("[\\0-\\t]");
}
}
if (result1 === null) {
if (/^[\x0B-\f]/.test(input.charAt(pos))) {
result1 = input.charAt(pos);
pos++;
} else {
result1 = null;
if (reportFailures === 0) {
matchFailed("[\\x0B-\\f]");
}
}
if (result1 === null) {
if (/^[\x0E-]/.test(input.charAt(pos))) {
result1 = input.charAt(pos);
pos++;
} else {
result1 = null;
if (reportFailures === 0) {
matchFailed("[\\x0E-]");
}
}
}
}
if (result1 !== null) {
result0 = [result0, result1];
} else {
result0 = null;
pos = pos0;
}
} else {
result0 = null;
pos = pos0;
}
return result0;
}
function parse_SIP_URI_noparams() {
var result0, result1, result2, result3;
var pos0, pos1;
pos0 = pos;
pos1 = pos;
result0 = parse_uri_scheme();
if (result0 !== null) {
if (input.charCodeAt(pos) === 58) {
result1 = ":";
pos++;
} else {
result1 = null;
if (reportFailures === 0) {
matchFailed("\":\"");
}
}
if (result1 !== null) {
result2 = parse_userinfo();
result2 = result2 !== null ? result2 : "";
if (result2 !== null) {
result3 = parse_hostport();
if (result3 !== null) {
result0 = [result0, result1, result2, result3];
} else {
result0 = null;
pos = pos1;
}
} else {
result0 = null;
pos = pos1;
}
} else {
result0 = null;
pos = pos1;
}
} else {
result0 = null;
pos = pos1;
}
if (result0 !== null) {
result0 = function (offset) {
try {
data.uri = new URI(data.scheme, data.user, data.host, data.port);
delete data.scheme;
delete data.user;
delete data.host;
delete data.host_type;
delete data.port;
} catch (e) {
data = -1;
}
}(pos0);
}
if (result0 === null) {
pos = pos0;
}
return result0;
}
function parse_SIP_URI() {
var result0, result1, result2, result3, result4, result5;
var pos0, pos1;
pos0 = pos;
pos1 = pos;
result0 = parse_uri_scheme();
if (result0 !== null) {
if (input.charCodeAt(pos) === 58) {
result1 = ":";
pos++;
} else {
result1 = null;
if (reportFailures === 0) {
matchFailed("\":\"");
}
}
if (result1 !== null) {
result2 = parse_userinfo();
result2 = result2 !== null ? result2 : "";
if (result2 !== null) {
result3 = parse_hostport();
if (result3 !== null) {
result4 = parse_uri_parameters();
if (result4 !== null) {
result5 = parse_headers();
result5 = result5 !== null ? result5 : "";
if (result5 !== null) {
result0 = [result0, result1, result2, result3, result4, result5];
} else {
result0 = null;
pos = pos1;
}
} else {
result0 = null;
pos = pos1;
}
} else {
result0 = null;
pos = pos1;
}
} else {
result0 = null;
pos = pos1;
}
} else {
result0 = null;
pos = pos1;
}
} else {
result0 = null;
pos = pos1;
}
if (result0 !== null) {
result0 = function (offset) {
var header;
try {
data.uri = new URI(data.scheme, data.user, data.host, data.port, data.uri_params, data.uri_headers);
delete data.scheme;
delete data.user;
delete data.host;
delete data.host_type;
delete data.port;
delete data.uri_params;
if (startRule === 'SIP_URI') {
data = data.uri;
}
} catch (e) {
data = -1;
}
}(pos0);
}
if (result0 === null) {
pos = pos0;
}
return result0;
}
function parse_uri_scheme() {
var result0;
result0 = parse_uri_scheme_sips();
if (result0 === null) {
result0 = parse_uri_scheme_sip();
}
return result0;
}
function parse_uri_scheme_sips() {
var result0;
var pos0;
pos0 = pos;
if (input.substr(pos, 4).toLowerCase() === "sips") {
result0 = input.substr(pos, 4);
pos += 4;
} else {
result0 = null;
if (reportFailures === 0) {
matchFailed("\"sips\"");
}
}
if (result0 !== null) {
result0 = function (offset, scheme) {
data.scheme = scheme.toLowerCase();
}(pos0, result0);
}
if (result0 === null) {
pos = pos0;
}
return result0;
}
function parse_uri_scheme_sip() {
var result0;
var pos0;
pos0 = pos;
if (input.substr(pos, 3).toLowerCase() === "sip") {
result0 = input.substr(pos, 3);
pos += 3;
} else {
result0 = null;
if (reportFailures === 0) {
matchFailed("\"sip\"");
}
}
if (result0 !== null) {
result0 = function (offset, scheme) {
data.scheme = scheme.toLowerCase();
}(pos0, result0);
}
if (result0 === null) {
pos = pos0;
}
return result0;
}
function parse_userinfo() {
var result0, result1, result2;
var pos0, pos1, pos2;
pos0 = pos;
pos1 = pos;
result0 = parse_user();
if (result0 !== null) {
pos2 = pos;
if (input.charCodeAt(pos) === 58) {
result1 = ":";
pos++;
} else {
result1 = null;
if (reportFailures === 0) {
matchFailed("\":\"");
}
}
if (result1 !== null) {
result2 = parse_password();
if (result2 !== null) {
result1 = [result1, result2];
} else {
result1 = null;
pos = pos2;
}
} else {
result1 = null;
pos = pos2;
}
result1 = result1 !== null ? result1 : "";
if (result1 !== null) {
if (input.charCodeAt(pos) === 64) {
result2 = "@";
pos++;
} else {
result2 = null;
if (reportFailures === 0) {
matchFailed("\"@\"");
}
}
if (result2 !== null) {
result0 = [result0, result1, result2];
} else {
result0 = null;
pos = pos1;
}
} else {
result0 = null;
pos = pos1;
}
} else {
result0 = null;
pos = pos1;
}
if (result0 !== null) {
result0 = function (offset) {
data.user = decodeURIComponent(input.substring(pos - 1, offset));
}(pos0);
}
if (result0 === null) {
pos = pos0;
}
return result0;
}
function parse_user() {
var result0, result1;
result1 = parse_unreserved();
if (result1 === null) {
result1 = parse_escaped();
if (result1 === null) {
result1 = parse_user_unreserved();
}
}
if (result1 !== null) {
result0 = [];
while (result1 !== null) {
result0.push(result1);
result1 = parse_unreserved();
if (result1 === null) {
result1 = parse_escaped();
if (result1 === null) {
result1 = parse_user_unreserved();
}
}
}
} else {
result0 = null;
}
return result0;
}
function parse_user_unreserved() {
var result0;
if (input.charCodeAt(pos) === 38) {
result0 = "&";
pos++;
} else {
result0 = null;
if (reportFailures === 0) {
matchFailed("\"&\"");
}
}
if (result0 === null) {
if (input.charCodeAt(pos) === 61) {
result0 = "=";
pos++;
} else {
result0 = null;
if (reportFailures === 0) {
matchFailed("\"=\"");
}
}
if (result0 === null) {
if (input.charCodeAt(pos) === 43) {
result0 = "+";
pos++;
} else {
result0 = null;
if (reportFailures === 0) {
matchFailed("\"+\"");
}
}
if (result0 === null) {
if (input.charCodeAt(pos) === 36) {
result0 = "$";
pos++;
} else {
result0 = null;
if (reportFailures === 0) {
matchFailed("\"$\"");
}
}
if (result0 === null) {
if (input.charCodeAt(pos) === 44) {
result0 = ",";
pos++;
} else {
result0 = null;
if (reportFailures === 0) {
matchFailed("\",\"");
}
}
if (result0 === null) {
if (input.charCodeAt(pos) === 59) {
result0 = ";";
pos++;
} else {
result0 = null;
if (reportFailures === 0) {
matchFailed("\";\"");
}
}
if (result0 === null) {
if (input.charCodeAt(pos) === 63) {
result0 = "?";
pos++;
} else {
result0 = null;
if (reportFailures === 0) {
matchFailed("\"?\"");
}
}
if (result0 === null) {
if (input.charCodeAt(pos) === 47) {
result0 = "/";
pos++;
} else {
result0 = null;
if (reportFailures === 0) {
matchFailed("\"/\"");
}
}
}
}
}
}
}
}
}
return result0;
}
function parse_password() {
var result0, result1;
var pos0;
pos0 = pos;
result0 = [];
result1 = parse_unreserved();
if (result1 === null) {
result1 = parse_escaped();
if (result1 === null) {
if (input.charCodeAt(pos) === 38) {
result1 = "&";
pos++;
} else {
result1 = null;
if (reportFailures === 0) {
matchFailed("\"&\"");
}
}
if (result1 === null) {
if (input.charCodeAt(pos) === 61) {
result1 = "=";
pos++;
} else {
result1 = null;
if (reportFailures === 0) {
matchFailed("\"=\"");
}
}
if (result1 === null) {
if (input.charCodeAt(pos) === 43) {
result1 = "+";
pos++;
} else {
result1 = null;
if (reportFailures === 0) {
matchFailed("\"+\"");
}
}
if (result1 === null) {
if (input.charCodeAt(pos) === 36) {
result1 = "$";
pos++;
} else {
result1 = null;
if (reportFailures === 0) {
matchFailed("\"$\"");
}
}
if (result1 === null) {
if (input.charCodeAt(pos) === 44) {
result1 = ",";
pos++;
} else {
result1 = null;
if (reportFailures === 0) {
matchFailed("\",\"");
}
}
}
}
}
}
}
}
while (result1 !== null) {
result0.push(result1);
result1 = parse_unreserved();
if (result1 === null) {
result1 = parse_escaped();
if (result1 === null) {
if (input.charCodeAt(pos) === 38) {
result1 = "&";
pos++;
} else {
result1 = null;
if (reportFailures === 0) {
matchFailed("\"&\"");
}
}
if (result1 === null) {
if (input.charCodeAt(pos) === 61) {
result1 = "=";
pos++;
} else {
result1 = null;
if (reportFailures === 0) {
matchFailed("\"=\"");
}
}
if (result1 === null) {
if (input.charCodeAt(pos) === 43) {
result1 = "+";
pos++;
} else {
result1 = null;
if (reportFailures === 0) {
matchFailed("\"+\"");
}
}
if (result1 === null) {
if (input.charCodeAt(pos) === 36) {
result1 = "$";
pos++;
} else {
result1 = null;
if (reportFailures === 0) {
matchFailed("\"$\"");
}
}
if (result1 === null) {
if (input.charCodeAt(pos) === 44) {
result1 = ",";
pos++;
} else {
result1 = null;
if (reportFailures === 0) {
matchFailed("\",\"");
}
}
}
}
}
}
}
}
}
if (result0 !== null) {
result0 = function (offset) {
data.password = input.substring(pos, offset);
}(pos0);
}
if (result0 === null) {
pos = pos0;
}
return result0;
}
function parse_hostport() {
var result0, result1, result2;
var pos0, pos1;
pos0 = pos;
result0 = parse_host();
if (result0 !== null) {
pos1 = pos;
if (input.charCodeAt(pos) === 58) {
result1 = ":";
pos++;
} else {
result1 = null;
if (reportFailures === 0) {
matchFailed("\":\"");
}
}
if (result1 !== null) {
result2 = parse_port();
if (result2 !== null) {
result1 = [result1, result2];
} else {
result1 = null;
pos = pos1;
}
} else {
result1 = null;
pos = pos1;
}
result1 = result1 !== null ? result1 : "";
if (result1 !== null) {
result0 = [result0, result1];
} else {
result0 = null;
pos = pos0;
}
} else {
result0 = null;
pos = pos0;
}
return result0;
}
function parse_host() {
var result0;
var pos0;
pos0 = pos;
result0 = parse_hostname();
if (result0 === null) {
result0 = parse_IPv4address();
if (result0 === null) {
result0 = parse_IPv6reference();
}
}
if (result0 !== null) {
result0 = function (offset) {
data.host = input.substring(pos, offset).toLowerCase();
return data.host;
}(pos0);
}
if (result0 === null) {
pos = pos0;
}
return result0;
}
function parse_hostname() {
var result0, result1, result2;
var pos0, pos1, pos2;
pos0 = pos;
pos1 = pos;
result0 = [];
pos2 = pos;
result1 = parse_domainlabel();
if (result1 !== null) {
if (input.charCodeAt(pos) === 46) {
result2 = ".";
pos++;
} else {
result2 = null;
if (reportFailures === 0) {
matchFailed("\".\"");
}
}
if (result2 !== null) {
result1 = [result1, result2];
} else {
result1 = null;
pos = pos2;
}
} else {
result1 = null;
pos = pos2;
}
while (result1 !== null) {
result0.push(result1);
pos2 = pos;
result1 = parse_domainlabel();
if (result1 !== null) {
if (input.charCodeAt(pos) === 46) {
result2 = ".";
pos++;
} else {
result2 = null;
if (reportFailures === 0) {
matchFailed("\".\"");
}
}
if (result2 !== null) {
result1 = [result1, result2];
} else {
result1 = null;
pos = pos2;
}
} else {
result1 = null;
pos = pos2;
}
}
if (result0 !== null) {
result1 = parse_toplabel();
if (result1 !== null) {
if (input.charCodeAt(pos) === 46) {
result2 = ".";
pos++;
} else {
result2 = null;
if (reportFailures === 0) {
matchFailed("\".\"");
}
}
result2 = result2 !== null ? result2 : "";
if (result2 !== null) {
result0 = [result0, result1, result2];
} else {
result0 = null;
pos = pos1;
}
} else {
result0 = null;
pos = pos1;
}
} else {
result0 = null;
pos = pos1;
}
if (result0 !== null) {
result0 = function (offset) {
data.host_type = 'domain';
return input.substring(pos, offset);
}(pos0);
}
if (result0 === null) {
pos = pos0;
}
return result0;
}
function parse_domainlabel() {
var result0, result1, result2;
var pos0;
pos0 = pos;
result0 = parse_alphanum();
if (result0 !== null) {
result1 = [];
result2 = parse_alphanum();
if (result2 === null) {
if (input.charCodeAt(pos) === 45) {
result2 = "-";
pos++;
} else {
result2 = null;
if (reportFailures === 0) {
matchFailed("\"-\"");
}
}
if (result2 === null) {
if (input.charCodeAt(pos) === 95) {
result2 = "_";
pos++;
} else {
result2 = null;
if (reportFailures === 0) {
matchFailed("\"_\"");
}
}
}
}
while (result2 !== null) {
result1.push(result2);
result2 = parse_alphanum();
if (result2 === null) {
if (input.charCodeAt(pos) === 45) {
result2 = "-";
pos++;
} else {
result2 = null;
if (reportFailures === 0) {
matchFailed("\"-\"");
}
}
if (result2 === null) {
if (input.charCodeAt(pos) === 95) {
result2 = "_";
pos++;
} else {
result2 = null;
if (reportFailures === 0) {
matchFailed("\"_\"");
}
}
}
}
}
if (result1 !== null) {
result0 = [result0, result1];
} else {
result0 = null;
pos = pos0;
}
} else {
result0 = null;
pos = pos0;
}
return result0;
}
function parse_toplabel() {
var result0, result1, result2;
var pos0;
pos0 = pos;
result0 = parse_ALPHA();
if (result0 !== null) {
result1 = [];
result2 = parse_alphanum();
if (result2 === null) {
if (input.charCodeAt(pos) === 45) {
result2 = "-";
pos++;
} else {
result2 = null;
if (reportFailures === 0) {
matchFailed("\"-\"");
}
}
if (result2 === null) {
if (input.charCodeAt(pos) === 95) {
result2 = "_";
pos++;
} else {
result2 = null;
if (reportFailures === 0) {
matchFailed("\"_\"");
}
}
}
}
while (result2 !== null) {
result1.push(result2);
result2 = parse_alphanum();
if (result2 === null) {
if (input.charCodeAt(pos) === 45) {
result2 = "-";
pos++;
} else {
result2 = null;
if (reportFailures === 0) {
matchFailed("\"-\"");
}
}
if (result2 === null) {
if (input.charCodeAt(pos) === 95) {
result2 = "_";
pos++;
} else {
result2 = null;
if (reportFailures === 0) {
matchFailed("\"_\"");
}
}
}
}
}
if (result1 !== null) {
result0 = [result0, result1];
} else {
result0 = null;
pos = pos0;
}
} else {
result0 = null;
pos = pos0;
}
return result0;
}
function parse_IPv6reference() {
var result0, result1, result2;
var pos0, pos1;
pos0 = pos;
pos1 = pos;
if (input.charCodeAt(pos) === 91) {
result0 = "[";
pos++;
} else {
result0 = null;
if (reportFailures === 0) {
matchFailed("\"[\"");
}
}
if (result0 !== null) {
result1 = parse_IPv6address();
if (result1 !== null) {
if (input.charCodeAt(pos) === 93) {
result2 = "]";
pos++;
} else {
result2 = null;
if (reportFailures === 0) {
matchFailed("\"]\"");
}
}
if (result2 !== null) {
result0 = [result0, result1, result2];
} else {
result0 = null;
pos = pos1;
}
} else {
result0 = null;
pos = pos1;
}
} else {
result0 = null;
pos = pos1;
}
if (result0 !== null) {
result0 = function (offset) {
data.host_type = 'IPv6';
return input.substring(pos, offset);
}(pos0);
}
if (result0 === null) {
pos = pos0;
}
return result0;
}
function parse_IPv6address() {
var result0, result1, result2, result3, result4, result5, result6, result7, result8, result9, result10, result11, result12;
var pos0, pos1, pos2;
pos0 = pos;
pos1 = pos;
result0 = parse_h16();
if (result0 !== null) {
if (input.charCodeAt(pos) === 58) {
result1 = ":";
pos++;
} else {
result1 = null;
if (reportFailures === 0) {
matchFailed("\":\"");
}
}
if (result1 !== null) {
result2 = parse_h16();
if (result2 !== null) {
if (input.charCodeAt(pos) === 58) {
result3 = ":";
pos++;
} else {
result3 = null;
if (reportFailures === 0) {
matchFailed("\":\"");
}
}
if (result3 !== null) {
result4 = parse_h16();
if (result4 !== null) {
if (input.charCodeAt(pos) === 58) {
result5 = ":";
pos++;
} else {
result5 = null;
if (reportFailures === 0) {
matchFailed("\":\"");
}
}
if (result5 !== null) {
result6 = parse_h16();
if (result6 !== null) {
if (input.charCodeAt(pos) === 58) {
result7 = ":";
pos++;
} else {
result7 = null;
if (reportFailures === 0) {
matchFailed("\":\"");
}
}
if (result7 !== null) {
result8 = parse_h16();
if (result8 !== null) {
if (input.charCodeAt(pos) === 58) {
result9 = ":";
pos++;
} else {
result9 = null;
if (reportFailures === 0) {
matchFailed("\":\"");
}
}
if (result9 !== null) {
result10 = parse_h16();
if (result10 !== null) {
if (input.charCodeAt(pos) === 58) {
result11 = ":";
pos++;
} else {
result11 = null;
if (reportFailures === 0) {
matchFailed("\":\"");
}
}
if (result11 !== null) {
result12 = parse_ls32();
if (result12 !== null) {
result0 = [result0, result1, result2, result3, result4, result5, result6, result7, result8, result9, result10, result11, result12];
} else {
result0 = null;
pos = pos1;
}
} else {
result0 = null;
pos = pos1;
}
} else {
result0 = null;
pos = pos1;
}
} else {
result0 = null;
pos = pos1;
}
} else {
result0 = null;
pos = pos1;
}
} else {
result0 = null;
pos = pos1;
}
} else {
result0 = null;
pos = pos1;
}
} else {
result0 = null;
pos = pos1;
}
} else {
result0 = null;
pos = pos1;
}
} else {
result0 = null;
pos = pos1;
}
} else {
result0 = null;
pos = pos1;
}
} else {
result0 = null;
pos = pos1;
}
} else {
result0 = null;
pos = pos1;
}
if (result0 === null) {
pos1 = pos;
if (input.substr(pos, 2) === "::") {
result0 = "::";
pos += 2;
} else {
result0 = null;
if (reportFailures === 0) {
matchFailed("\"::\"");
}
}
if (result0 !== null) {
result1 = parse_h16();
if (result1 !== null) {
if (input.charCodeAt(pos) === 58) {
result2 = ":";
pos++;
} else {
result2 = null;
if (reportFailures === 0) {
matchFailed("\":\"");
}
}
if (result2 !== null) {
result3 = parse_h16();
if (result3 !== null) {
if (input.charCodeAt(pos) === 58) {
result4 = ":";
pos++;
} else {
result4 = null;
if (reportFailures === 0) {
matchFailed("\":\"");
}
}
if (result4 !== null) {
result5 = parse_h16();
if (result5 !== null) {
if (input.charCodeAt(pos) === 58) {
result6 = ":";
pos++;
} else {
result6 = null;
if (reportFailures === 0) {
matchFailed("\":\"");
}
}
if (result6 !== null) {
result7 = parse_h16();
if (result7 !== null) {
if (input.charCodeAt(pos) === 58) {
result8 = ":";
pos++;
} else {
result8 = null;
if (reportFailures === 0) {
matchFailed("\":\"");
}
}
if (result8 !== null) {
result9 = parse_h16();
if (result9 !== null) {
if (input.charCodeAt(pos) === 58) {
result10 = ":";
pos++;
} else {
result10 = null;
if (reportFailures === 0) {
matchFailed("\":\"");
}
}
if (result10 !== null) {
result11 = parse_ls32();
if (result11 !== null) {
result0 = [result0, result1, result2, result3, result4, result5, result6, result7, result8, result9, result10, result11];
} else {
result0 = null;
pos = pos1;
}
} else {
result0 = null;
pos = pos1;
}
} else {
result0 = null;
pos = pos1;
}
} else {
result0 = null;
pos = pos1;
}
} else {
result0 = null;
pos = pos1;
}
} else {
result0 = null;
pos = pos1;
}
} else {
result0 = null;
pos = pos1;
}
} else {
result0 = null;
pos = pos1;
}
} else {
result0 = null;
pos = pos1;
}
} else {
result0 = null;
pos = pos1;
}
} else {
result0 = null;
pos = pos1;
}
} else {
result0 = null;
pos = pos1;
}
if (result0 === null) {
pos1 = pos;
if (input.substr(pos, 2) === "::") {
result0 = "::";
pos += 2;
} else {
result0 = null;
if (reportFailures === 0) {
matchFailed("\"::\"");
}
}
if (result0 !== null) {
result1 = parse_h16();
if (result1 !== null) {
if (input.charCodeAt(pos) === 58) {
result2 = ":";
pos++;
} else {
result2 = null;
if (reportFailures === 0) {
matchFailed("\":\"");
}
}
if (result2 !== null) {
result3 = parse_h16();
if (result3 !== null) {
if (input.charCodeAt(pos) === 58) {
result4 = ":";
pos++;
} else {
result4 = null;
if (reportFailures === 0) {
matchFailed("\":\"");
}
}
if (result4 !== null) {
result5 = parse_h16();
if (result5 !== null) {
if (input.charCodeAt(pos) === 58) {
result6 = ":";
pos++;
} else {
result6 = null;
if (reportFailures === 0) {
matchFailed("\":\"");
}
}
if (result6 !== null) {
result7 = parse_h16();
if (result7 !== null) {
if (input.charCodeAt(pos) === 58) {
result8 = ":";
pos++;
} else {
result8 = null;
if (reportFailures === 0) {
matchFailed("\":\"");
}
}
if (result8 !== null) {
result9 = parse_ls32();
if (result9 !== null) {
result0 = [result0, result1, result2, result3, result4, result5, result6, result7, result8, result9];
} else {
result0 = null;
pos = pos1;
}
} else {
result0 = null;
pos = pos1;
}
} else {
result0 = null;
pos = pos1;
}
} else {
result0 = null;
pos = pos1;
}
} else {
result0 = null;
pos = pos1;
}
} else {
result0 = null;
pos = pos1;
}
} else {
result0 = null;
pos = pos1;
}
} else {
result0 = null;
pos = pos1;
}
} else {
result0 = null;
pos = pos1;
}
} else {
result0 = null;
pos = pos1;
}
if (result0 === null) {
pos1 = pos;
if (input.substr(pos, 2) === "::") {
result0 = "::";
pos += 2;
} else {
result0 = null;
if (reportFailures === 0) {
matchFailed("\"::\"");
}
}
if (result0 !== null) {
result1 = parse_h16();
if (result1 !== null) {
if (input.charCodeAt(pos) === 58) {
result2 = ":";
pos++;
} else {
result2 = null;
if (reportFailures === 0) {
matchFailed("\":\"");
}
}
if (result2 !== null) {
result3 = parse_h16();
if (result3 !== null) {
if (input.charCodeAt(pos) === 58) {
result4 = ":";
pos++;
} else {
result4 = null;
if (reportFailures === 0) {
matchFailed("\":\"");
}
}
if (result4 !== null) {
result5 = parse_h16();
if (result5 !== null) {
if (input.charCodeAt(pos) === 58) {
result6 = ":";
pos++;
} else {
result6 = null;
if (reportFailures === 0) {
matchFailed("\":\"");
}
}
if (result6 !== null) {
result7 = parse_ls32();
if (result7 !== null) {
result0 = [result0, result1, result2, result3, result4, result5, result6, result7];
} else {
result0 = null;
pos = pos1;
}
} else {
result0 = null;
pos = pos1;
}
} else {
result0 = null;
pos = pos1;
}
} else {
result0 = null;
pos = pos1;
}
} else {
result0 = null;
pos = pos1;
}
} else {
result0 = null;
pos = pos1;
}
} else {
result0 = null;
pos = pos1;
}
} else {
result0 = null;
pos = pos1;
}
if (result0 === null) {
pos1 = pos;
if (input.substr(pos, 2) === "::") {
result0 = "::";
pos += 2;
} else {
result0 = null;
if (reportFailures === 0) {
matchFailed("\"::\"");
}
}
if (result0 !== null) {
result1 = parse_h16();
if (result1 !== null) {
if (input.charCodeAt(pos) === 58) {
result2 = ":";
pos++;
} else {
result2 = null;
if (reportFailures === 0) {
matchFailed("\":\"");
}
}
if (result2 !== null) {
result3 = parse_h16();
if (result3 !== null) {
if (input.charCodeAt(pos) === 58) {
result4 = ":";
pos++;
} else {
result4 = null;
if (reportFailures === 0) {
matchFailed("\":\"");
}
}
if (result4 !== null) {
result5 = parse_ls32();
if (result5 !== null) {
result0 = [result0, result1, result2, result3, result4, result5];
} else {
result0 = null;
pos = pos1;
}
} else {
result0 = null;
pos = pos1;
}
} else {
result0 = null;
pos = pos1;
}
} else {
result0 = null;
pos = pos1;
}
} else {
result0 = null;
pos = pos1;
}
} else {
result0 = null;
pos = pos1;
}
if (result0 === null) {
pos1 = pos;
if (input.substr(pos, 2) === "::") {
result0 = "::";
pos += 2;
} else {
result0 = null;
if (reportFailures === 0) {
matchFailed("\"::\"");
}
}
if (result0 !== null) {
result1 = parse_h16();
if (result1 !== null) {
if (input.charCodeAt(pos) === 58) {
result2 = ":";
pos++;
} else {
result2 = null;
if (reportFailures === 0) {
matchFailed("\":\"");
}
}
if (result2 !== null) {
result3 = parse_ls32();
if (result3 !== null) {
result0 = [result0, result1, result2, result3];
} else {
result0 = null;
pos = pos1;
}
} else {
result0 = null;
pos = pos1;
}
} else {
result0 = null;
pos = pos1;
}
} else {
result0 = null;
pos = pos1;
}
if (result0 === null) {
pos1 = pos;
if (input.substr(pos, 2) === "::") {
result0 = "::";
pos += 2;
} else {
result0 = null;
if (reportFailures === 0) {
matchFailed("\"::\"");
}
}
if (result0 !== null) {
result1 = parse_ls32();
if (result1 !== null) {
result0 = [result0, result1];
} else {
result0 = null;
pos = pos1;
}
} else {
result0 = null;
pos = pos1;
}
if (result0 === null) {
pos1 = pos;
if (input.substr(pos, 2) === "::") {
result0 = "::";
pos += 2;
} else {
result0 = null;
if (reportFailures === 0) {
matchFailed("\"::\"");
}
}
if (result0 !== null) {
result1 = parse_h16();
if (result1 !== null) {
result0 = [result0, result1];
} else {
result0 = null;
pos = pos1;
}
} else {
result0 = null;
pos = pos1;
}
if (result0 === null) {
pos1 = pos;
result0 = parse_h16();
if (result0 !== null) {
if (input.substr(pos, 2) === "::") {
result1 = "::";
pos += 2;
} else {
result1 = null;
if (reportFailures === 0) {
matchFailed("\"::\"");
}
}
if (result1 !== null) {
result2 = parse_h16();
if (result2 !== null) {
if (input.charCodeAt(pos) === 58) {
result3 = ":";
pos++;
} else {
result3 = null;
if (reportFailures === 0) {
matchFailed("\":\"");
}
}
if (result3 !== null) {
result4 = parse_h16();
if (result4 !== null) {
if (input.charCodeAt(pos) === 58) {
result5 = ":";
pos++;
} else {
result5 = null;
if (reportFailures === 0) {
matchFailed("\":\"");
}
}
if (result5 !== null) {
result6 = parse_h16();
if (result6 !== null) {
if (input.charCodeAt(pos) === 58) {
result7 = ":";
pos++;
} else {
result7 = null;
if (reportFailures === 0) {
matchFailed("\":\"");
}
}
if (result7 !== null) {
result8 = parse_h16();
if (result8 !== null) {
if (input.charCodeAt(pos) === 58) {
result9 = ":";
pos++;
} else {
result9 = null;
if (reportFailures === 0) {
matchFailed("\":\"");
}
}
if (result9 !== null) {
result10 = parse_ls32();
if (result10 !== null) {
result0 = [result0, result1, result2, result3, result4, result5, result6, result7, result8, result9, result10];
} else {
result0 = null;
pos = pos1;
}
} else {
result0 = null;
pos = pos1;
}
} else {
result0 = null;
pos = pos1;
}
} else {
result0 = null;
pos = pos1;
}
} else {
result0 = null;
pos = pos1;
}
} else {
result0 = null;
pos = pos1;
}
} else {
result0 = null;
pos = pos1;
}
} else {
result0 = null;
pos = pos1;
}
} else {
result0 = null;
pos = pos1;
}
} else {
result0 = null;
pos = pos1;
}
} else {
result0 = null;
pos = pos1;
}
if (result0 === null) {
pos1 = pos;
result0 = parse_h16();
if (result0 !== null) {
pos2 = pos;
if (input.charCodeAt(pos) === 58) {
result1 = ":";
pos++;
} else {
result1 = null;
if (reportFailures === 0) {
matchFailed("\":\"");
}
}
if (result1 !== null) {
result2 = parse_h16();
if (result2 !== null) {
result1 = [result1, result2];
} else {
result1 = null;
pos = pos2;
}
} else {
result1 = null;
pos = pos2;
}
result1 = result1 !== null ? result1 : "";
if (result1 !== null) {
if (input.substr(pos, 2) === "::") {
result2 = "::";
pos += 2;
} else {
result2 = null;
if (reportFailures === 0) {
matchFailed("\"::\"");
}
}
if (result2 !== null) {
result3 = parse_h16();
if (result3 !== null) {
if (input.charCodeAt(pos) === 58) {
result4 = ":";
pos++;
} else {
result4 = null;
if (reportFailures === 0) {
matchFailed("\":\"");
}
}
if (result4 !== null) {
result5 = parse_h16();
if (result5 !== null) {
if (input.charCodeAt(pos) === 58) {
result6 = ":";
pos++;
} else {
result6 = null;
if (reportFailures === 0) {
matchFailed("\":\"");
}
}
if (result6 !== null) {
result7 = parse_h16();
if (result7 !== null) {
if (input.charCodeAt(pos) === 58) {
result8 = ":";
pos++;
} else {
result8 = null;
if (reportFailures === 0) {
matchFailed("\":\"");
}
}
if (result8 !== null) {
result9 = parse_ls32();
if (result9 !== null) {
result0 = [result0, result1, result2, result3, result4, result5, result6, result7, result8, result9];
} else {
result0 = null;
pos = pos1;
}
} else {
result0 = null;
pos = pos1;
}
} else {
result0 = null;
pos = pos1;
}
} else {
result0 = null;
pos = pos1;
}
} else {
result0 = null;
pos = pos1;
}
} else {
result0 = null;
pos = pos1;
}
} else {
result0 = null;
pos = pos1;
}
} else {
result0 = null;
pos = pos1;
}
} else {
result0 = null;
pos = pos1;
}
} else {
result0 = null;
pos = pos1;
}
if (result0 === null) {
pos1 = pos;
result0 = parse_h16();
if (result0 !== null) {
pos2 = pos;
if (input.charCodeAt(pos) === 58) {
result1 = ":";
pos++;
} else {
result1 = null;
if (reportFailures === 0) {
matchFailed("\":\"");
}
}
if (result1 !== null) {
result2 = parse_h16();
if (result2 !== null) {
result1 = [result1, result2];
} else {
result1 = null;
pos = pos2;
}
} else {
result1 = null;
pos = pos2;
}
result1 = result1 !== null ? result1 : "";
if (result1 !== null) {
pos2 = pos;
if (input.charCodeAt(pos) === 58) {
result2 = ":";
pos++;
} else {
result2 = null;
if (reportFailures === 0) {
matchFailed("\":\"");
}
}
if (result2 !== null) {
result3 = parse_h16();
if (result3 !== null) {
result2 = [result2, result3];
} else {
result2 = null;
pos = pos2;
}
} else {
result2 = null;
pos = pos2;
}
result2 = result2 !== null ? result2 : "";
if (result2 !== null) {
if (input.substr(pos, 2) === "::") {
result3 = "::";
pos += 2;
} else {
result3 = null;
if (reportFailures === 0) {
matchFailed("\"::\"");
}
}
if (result3 !== null) {
result4 = parse_h16();
if (result4 !== null) {
if (input.charCodeAt(pos) === 58) {
result5 = ":";
pos++;
} else {
result5 = null;
if (reportFailures === 0) {
matchFailed("\":\"");
}
}
if (result5 !== null) {
result6 = parse_h16();
if (result6 !== null) {
if (input.charCodeAt(pos) === 58) {
result7 = ":";
pos++;
} else {
result7 = null;
if (reportFailures === 0) {
matchFailed("\":\"");
}
}
if (result7 !== null) {
result8 = parse_ls32();
if (result8 !== null) {
result0 = [result0, result1, result2, result3, result4, result5, result6, result7, result8];
} else {
result0 = null;
pos = pos1;
}
} else {
result0 = null;
pos = pos1;
}
} else {
result0 = null;
pos = pos1;
}
} else {
result0 = null;
pos = pos1;
}
} else {
result0 = null;
pos = pos1;
}
} else {
result0 = null;
pos = pos1;
}
} else {
result0 = null;
pos = pos1;
}
} else {
result0 = null;
pos = pos1;
}
} else {
result0 = null;
pos = pos1;
}
if (result0 === null) {
pos1 = pos;
result0 = parse_h16();
if (result0 !== null) {
pos2 = pos;
if (input.charCodeAt(pos) === 58) {
result1 = ":";
pos++;
} else {
result1 = null;
if (reportFailures === 0) {
matchFailed("\":\"");
}
}
if (result1 !== null) {
result2 = parse_h16();
if (result2 !== null) {
result1 = [result1, result2];
} else {
result1 = null;
pos = pos2;
}
} else {
result1 = null;
pos = pos2;
}
result1 = result1 !== null ? result1 : "";
if (result1 !== null) {
pos2 = pos;
if (input.charCodeAt(pos) === 58) {
result2 = ":";
pos++;
} else {
result2 = null;
if (reportFailures === 0) {
matchFailed("\":\"");
}
}
if (result2 !== null) {
result3 = parse_h16();
if (result3 !== null) {
result2 = [result2, result3];
} else {
result2 = null;
pos = pos2;
}
} else {
result2 = null;
pos = pos2;
}
result2 = result2 !== null ? result2 : "";
if (result2 !== null) {
pos2 = pos;
if (input.charCodeAt(pos) === 58) {
result3 = ":";
pos++;
} else {
result3 = null;
if (reportFailures === 0) {
matchFailed("\":\"");
}
}
if (result3 !== null) {
result4 = parse_h16();
if (result4 !== null) {
result3 = [result3, result4];
} else {
result3 = null;
pos = pos2;
}
} else {
result3 = null;
pos = pos2;
}
result3 = result3 !== null ? result3 : "";
if (result3 !== null) {
if (input.substr(pos, 2) === "::") {
result4 = "::";
pos += 2;
} else {
result4 = null;
if (reportFailures === 0) {
matchFailed("\"::\"");
}
}
if (result4 !== null) {
result5 = parse_h16();
if (result5 !== null) {
if (input.charCodeAt(pos) === 58) {
result6 = ":";
pos++;
} else {
result6 = null;
if (reportFailures === 0) {
matchFailed("\":\"");
}
}
if (result6 !== null) {
result7 = parse_ls32();
if (result7 !== null) {
result0 = [result0, result1, result2, result3, result4, result5, result6, result7];
} else {
result0 = null;
pos = pos1;
}
} else {
result0 = null;
pos = pos1;
}
} else {
result0 = null;
pos = pos1;
}
} else {
result0 = null;
pos = pos1;
}
} else {
result0 = null;
pos = pos1;
}
} else {
result0 = null;
pos = pos1;
}
} else {
result0 = null;
pos = pos1;
}
} else {
result0 = null;
pos = pos1;
}
if (result0 === null) {
pos1 = pos;
result0 = parse_h16();
if (result0 !== null) {
pos2 = pos;
if (input.charCodeAt(pos) === 58) {
result1 = ":";
pos++;
} else {
result1 = null;
if (reportFailures === 0) {
matchFailed("\":\"");
}
}
if (result1 !== null) {
result2 = parse_h16();
if (result2 !== null) {
result1 = [result1, result2];
} else {
result1 = null;
pos = pos2;
}
} else {
result1 = null;
pos = pos2;
}
result1 = result1 !== null ? result1 : "";
if (result1 !== null) {
pos2 = pos;
if (input.charCodeAt(pos) === 58) {
result2 = ":";
pos++;
} else {
result2 = null;
if (reportFailures === 0) {
matchFailed("\":\"");
}
}
if (result2 !== null) {
result3 = parse_h16();
if (result3 !== null) {
result2 = [result2, result3];
} else {
result2 = null;
pos = pos2;
}
} else {
result2 = null;
pos = pos2;
}
result2 = result2 !== null ? result2 : "";
if (result2 !== null) {
pos2 = pos;
if (input.charCodeAt(pos) === 58) {
result3 = ":";
pos++;
} else {
result3 = null;
if (reportFailures === 0) {
matchFailed("\":\"");
}
}
if (result3 !== null) {
result4 = parse_h16();
if (result4 !== null) {
result3 = [result3, result4];
} else {
result3 = null;
pos = pos2;
}
} else {
result3 = null;
pos = pos2;
}
result3 = result3 !== null ? result3 : "";
if (result3 !== null) {
pos2 = pos;
if (input.charCodeAt(pos) === 58) {
result4 = ":";
pos++;
} else {
result4 = null;
if (reportFailures === 0) {
matchFailed("\":\"");
}
}
if (result4 !== null) {
result5 = parse_h16();
if (result5 !== null) {
result4 = [result4, result5];
} else {
result4 = null;
pos = pos2;
}
} else {
result4 = null;
pos = pos2;
}
result4 = result4 !== null ? result4 : "";
if (result4 !== null) {
if (input.substr(pos, 2) === "::") {
result5 = "::";
pos += 2;
} else {
result5 = null;
if (reportFailures === 0) {
matchFailed("\"::\"");
}
}
if (result5 !== null) {
result6 = parse_ls32();
if (result6 !== null) {
result0 = [result0, result1, result2, result3, result4, result5, result6];
} else {
result0 = null;
pos = pos1;
}
} else {
result0 = null;
pos = pos1;
}
} else {
result0 = null;
pos = pos1;
}
} else {
result0 = null;
pos = pos1;
}
} else {
result0 = null;
pos = pos1;
}
} else {
result0 = null;
pos = pos1;
}
} else {
result0 = null;
pos = pos1;
}
if (result0 === null) {
pos1 = pos;
result0 = parse_h16();
if (result0 !== null) {
pos2 = pos;
if (input.charCodeAt(pos) === 58) {
result1 = ":";
pos++;
} else {
result1 = null;
if (reportFailures === 0) {
matchFailed("\":\"");
}
}
if (result1 !== null) {
result2 = parse_h16();
if (result2 !== null) {
result1 = [result1, result2];
} else {
result1 = null;
pos = pos2;
}
} else {
result1 = null;
pos = pos2;
}
result1 = result1 !== null ? result1 : "";
if (result1 !== null) {
pos2 = pos;
if (input.charCodeAt(pos) === 58) {
result2 = ":";
pos++;
} else {
result2 = null;
if (reportFailures === 0) {
matchFailed("\":\"");
}
}
if (result2 !== null) {
result3 = parse_h16();
if (result3 !== null) {
result2 = [result2, result3];
} else {
result2 = null;
pos = pos2;
}
} else {
result2 = null;
pos = pos2;
}
result2 = result2 !== null ? result2 : "";
if (result2 !== null) {
pos2 = pos;
if (input.charCodeAt(pos) === 58) {
result3 = ":";
pos++;
} else {
result3 = null;
if (reportFailures === 0) {
matchFailed("\":\"");
}
}
if (result3 !== null) {
result4 = parse_h16();
if (result4 !== null) {
result3 = [result3, result4];
} else {
result3 = null;
pos = pos2;
}
} else {
result3 = null;
pos = pos2;
}
result3 = result3 !== null ? result3 : "";
if (result3 !== null) {
pos2 = pos;
if (input.charCodeAt(pos) === 58) {
result4 = ":";
pos++;
} else {
result4 = null;
if (reportFailures === 0) {
matchFailed("\":\"");
}
}
if (result4 !== null) {
result5 = parse_h16();
if (result5 !== null) {
result4 = [result4, result5];
} else {
result4 = null;
pos = pos2;
}
} else {
result4 = null;
pos = pos2;
}
result4 = result4 !== null ? result4 : "";
if (result4 !== null) {
pos2 = pos;
if (input.charCodeAt(pos) === 58) {
result5 = ":";
pos++;
} else {
result5 = null;
if (reportFailures === 0) {
matchFailed("\":\"");
}
}
if (result5 !== null) {
result6 = parse_h16();
if (result6 !== null) {
result5 = [result5, result6];
} else {
result5 = null;
pos = pos2;
}
} else {
result5 = null;
pos = pos2;
}
result5 = result5 !== null ? result5 : "";
if (result5 !== null) {
if (input.substr(pos, 2) === "::") {
result6 = "::";
pos += 2;
} else {
result6 = null;
if (reportFailures === 0) {
matchFailed("\"::\"");
}
}
if (result6 !== null) {
result7 = parse_h16();
if (result7 !== null) {
result0 = [result0, result1, result2, result3, result4, result5, result6, result7];
} else {
result0 = null;
pos = pos1;
}
} else {
result0 = null;
pos = pos1;
}
} else {
result0 = null;
pos = pos1;
}
} else {
result0 = null;
pos = pos1;
}
} else {
result0 = null;
pos = pos1;
}
} else {
result0 = null;
pos = pos1;
}
} else {
result0 = null;
pos = pos1;
}
} else {
result0 = null;
pos = pos1;
}
if (result0 === null) {
pos1 = pos;
result0 = parse_h16();
if (result0 !== null) {
pos2 = pos;
if (input.charCodeAt(pos) === 58) {
result1 = ":";
pos++;
} else {
result1 = null;
if (reportFailures === 0) {
matchFailed("\":\"");
}
}
if (result1 !== null) {
result2 = parse_h16();
if (result2 !== null) {
result1 = [result1, result2];
} else {
result1 = null;
pos = pos2;
}
} else {
result1 = null;
pos = pos2;
}
result1 = result1 !== null ? result1 : "";
if (result1 !== null) {
pos2 = pos;
if (input.charCodeAt(pos) === 58) {
result2 = ":";
pos++;
} else {
result2 = null;
if (reportFailures === 0) {
matchFailed("\":\"");
}
}
if (result2 !== null) {
result3 = parse_h16();
if (result3 !== null) {
result2 = [result2, result3];
} else {
result2 = null;
pos = pos2;
}
} else {
result2 = null;
pos = pos2;
}
result2 = result2 !== null ? result2 : "";
if (result2 !== null) {
pos2 = pos;
if (input.charCodeAt(pos) === 58) {
result3 = ":";
pos++;
} else {
result3 = null;
if (reportFailures === 0) {
matchFailed("\":\"");
}
}
if (result3 !== null) {
result4 = parse_h16();
if (result4 !== null) {
result3 = [result3, result4];
} else {
result3 = null;
pos = pos2;
}
} else {
result3 = null;
pos = pos2;
}
result3 = result3 !== null ? result3 : "";
if (result3 !== null) {
pos2 = pos;
if (input.charCodeAt(pos) === 58) {
result4 = ":";
pos++;
} else {
result4 = null;
if (reportFailures === 0) {
matchFailed("\":\"");
}
}
if (result4 !== null) {
result5 = parse_h16();
if (result5 !== null) {
result4 = [result4, result5];
} else {
result4 = null;
pos = pos2;
}
} else {
result4 = null;
pos = pos2;
}
result4 = result4 !== null ? result4 : "";
if (result4 !== null) {
pos2 = pos;
if (input.charCodeAt(pos) === 58) {
result5 = ":";
pos++;
} else {
result5 = null;
if (reportFailures === 0) {
matchFailed("\":\"");
}
}
if (result5 !== null) {
result6 = parse_h16();
if (result6 !== null) {
result5 = [result5, result6];
} else {
result5 = null;
pos = pos2;
}
} else {
result5 = null;
pos = pos2;
}
result5 = result5 !== null ? result5 : "";
if (result5 !== null) {
pos2 = pos;
if (input.charCodeAt(pos) === 58) {
result6 = ":";
pos++;
} else {
result6 = null;
if (reportFailures === 0) {
matchFailed("\":\"");
}
}
if (result6 !== null) {
result7 = parse_h16();
if (result7 !== null) {
result6 = [result6, result7];
} else {
result6 = null;
pos = pos2;
}
} else {
result6 = null;
pos = pos2;
}
result6 = result6 !== null ? result6 : "";
if (result6 !== null) {
if (input.substr(pos, 2) === "::") {
result7 = "::";
pos += 2;
} else {
result7 = null;
if (reportFailures === 0) {
matchFailed("\"::\"");
}
}
if (result7 !== null) {
result0 = [result0, result1, result2, result3, result4, result5, result6, result7];
} else {
result0 = null;
pos = pos1;
}
} else {
result0 = null;
pos = pos1;
}
} else {
result0 = null;
pos = pos1;
}
} else {
result0 = null;
pos = pos1;
}
} else {
result0 = null;
pos = pos1;
}
} else {
result0 = null;
pos = pos1;
}
} else {
result0 = null;
pos = pos1;
}
} else {
result0 = null;
pos = pos1;
}
}
}
}
}
}
}
}
}
}
}
}
}
}
}
if (result0 !== null) {
result0 = function (offset) {
data.host_type = 'IPv6';
return input.substring(pos, offset);
}(pos0);
}
if (result0 === null) {
pos = pos0;
}
return result0;
}
function parse_h16() {
var result0, result1, result2, result3;
var pos0;
pos0 = pos;
result0 = parse_HEXDIG();
if (result0 !== null) {
result1 = parse_HEXDIG();
result1 = result1 !== null ? result1 : "";
if (result1 !== null) {
result2 = parse_HEXDIG();
result2 = result2 !== null ? result2 : "";
if (result2 !== null) {
result3 = parse_HEXDIG();
result3 = result3 !== null ? result3 : "";
if (result3 !== null) {
result0 = [result0, result1, result2, result3];
} else {
result0 = null;
pos = pos0;
}
} else {
result0 = null;
pos = pos0;
}
} else {
result0 = null;
pos = pos0;
}
} else {
result0 = null;
pos = pos0;
}
return result0;
}
function parse_ls32() {
var result0, result1, result2;
var pos0;
pos0 = pos;
result0 = parse_h16();
if (result0 !== null) {
if (input.charCodeAt(pos) === 58) {
result1 = ":";
pos++;
} else {
result1 = null;
if (reportFailures === 0) {
matchFailed("\":\"");
}
}
if (result1 !== null) {
result2 = parse_h16();
if (result2 !== null) {
result0 = [result0, result1, result2];
} else {
result0 = null;
pos = pos0;
}
} else {
result0 = null;
pos = pos0;
}
} else {
result0 = null;
pos = pos0;
}
if (result0 === null) {
result0 = parse_IPv4address();
}
return result0;
}
function parse_IPv4address() {
var result0, result1, result2, result3, result4, result5, result6;
var pos0, pos1;
pos0 = pos;
pos1 = pos;
result0 = parse_dec_octet();
if (result0 !== null) {
if (input.charCodeAt(pos) === 46) {
result1 = ".";
pos++;
} else {
result1 = null;
if (reportFailures === 0) {
matchFailed("\".\"");
}
}
if (result1 !== null) {
result2 = parse_dec_octet();
if (result2 !== null) {
if (input.charCodeAt(pos) === 46) {
result3 = ".";
pos++;
} else {
result3 = null;
if (reportFailures === 0) {
matchFailed("\".\"");
}
}
if (result3 !== null) {
result4 = parse_dec_octet();
if (result4 !== null) {
if (input.charCodeAt(pos) === 46) {
result5 = ".";
pos++;
} else {
result5 = null;
if (reportFailures === 0) {
matchFailed("\".\"");
}
}
if (result5 !== null) {
result6 = parse_dec_octet();
if (result6 !== null) {
result0 = [result0, result1, result2, result3, result4, result5, result6];
} else {
result0 = null;
pos = pos1;
}
} else {
result0 = null;
pos = pos1;
}
} else {
result0 = null;
pos = pos1;
}
} else {
result0 = null;
pos = pos1;
}
} else {
result0 = null;
pos = pos1;
}
} else {
result0 = null;
pos = pos1;
}
} else {
result0 = null;
pos = pos1;
}
if (result0 !== null) {
result0 = function (offset) {
data.host_type = 'IPv4';
return input.substring(pos, offset);
}(pos0);
}
if (result0 === null) {
pos = pos0;
}
return result0;
}
function parse_dec_octet() {
var result0, result1, result2;
var pos0;
pos0 = pos;
if (input.substr(pos, 2) === "25") {
result0 = "25";
pos += 2;
} else {
result0 = null;
if (reportFailures === 0) {
matchFailed("\"25\"");
}
}
if (result0 !== null) {
if (/^[0-5]/.test(input.charAt(pos))) {
result1 = input.charAt(pos);
pos++;
} else {
result1 = null;
if (reportFailures === 0) {
matchFailed("[0-5]");
}
}
if (result1 !== null) {
result0 = [result0, result1];
} else {
result0 = null;
pos = pos0;
}
} else {
result0 = null;
pos = pos0;
}
if (result0 === null) {
pos0 = pos;
if (input.charCodeAt(pos) === 50) {
result0 = "2";
pos++;
} else {
result0 = null;
if (reportFailures === 0) {
matchFailed("\"2\"");
}
}
if (result0 !== null) {
if (/^[0-4]/.test(input.charAt(pos))) {
result1 = input.charAt(pos);
pos++;
} else {
result1 = null;
if (reportFailures === 0) {
matchFailed("[0-4]");
}
}
if (result1 !== null) {
result2 = parse_DIGIT();
if (result2 !== null) {
result0 = [result0, result1, result2];
} else {
result0 = null;
pos = pos0;
}
} else {
result0 = null;
pos = pos0;
}
} else {
result0 = null;
pos = pos0;
}
if (result0 === null) {
pos0 = pos;
if (input.charCodeAt(pos) === 49) {
result0 = "1";
pos++;
} else {
result0 = null;
if (reportFailures === 0) {
matchFailed("\"1\"");
}
}
if (result0 !== null) {
result1 = parse_DIGIT();
if (result1 !== null) {
result2 = parse_DIGIT();
if (result2 !== null) {
result0 = [result0, result1, result2];
} else {
result0 = null;
pos = pos0;
}
} else {
result0 = null;
pos = pos0;
}
} else {
result0 = null;
pos = pos0;
}
if (result0 === null) {
pos0 = pos;
if (/^[1-9]/.test(input.charAt(pos))) {
result0 = input.charAt(pos);
pos++;
} else {
result0 = null;
if (reportFailures === 0) {
matchFailed("[1-9]");
}
}
if (result0 !== null) {
result1 = parse_DIGIT();
if (result1 !== null) {
result0 = [result0, result1];
} else {
result0 = null;
pos = pos0;
}
} else {
result0 = null;
pos = pos0;
}
if (result0 === null) {
result0 = parse_DIGIT();
}
}
}
}
return result0;
}
function parse_port() {
var result0, result1, result2, result3, result4;
var pos0, pos1;
pos0 = pos;
pos1 = pos;
result0 = parse_DIGIT();
result0 = result0 !== null ? result0 : "";
if (result0 !== null) {
result1 = parse_DIGIT();
result1 = result1 !== null ? result1 : "";
if (result1 !== null) {
result2 = parse_DIGIT();
result2 = result2 !== null ? result2 : "";
if (result2 !== null) {
result3 = parse_DIGIT();
result3 = result3 !== null ? result3 : "";
if (result3 !== null) {
result4 = parse_DIGIT();
result4 = result4 !== null ? result4 : "";
if (result4 !== null) {
result0 = [result0, result1, result2, result3, result4];
} else {
result0 = null;
pos = pos1;
}
} else {
result0 = null;
pos = pos1;
}
} else {
result0 = null;
pos = pos1;
}
} else {
result0 = null;
pos = pos1;
}
} else {
result0 = null;
pos = pos1;
}
if (result0 !== null) {
result0 = function (offset, port) {
port = parseInt(port.join(''));
data.port = port;
return port;
}(pos0, result0);
}
if (result0 === null) {
pos = pos0;
}
return result0;
}
function parse_uri_parameters() {
var result0, result1, result2;
var pos0;
result0 = [];
pos0 = pos;
if (input.charCodeAt(pos) === 59) {
result1 = ";";
pos++;
} else {
result1 = null;
if (reportFailures === 0) {
matchFailed("\";\"");
}
}
if (result1 !== null) {
result2 = parse_uri_parameter();
if (result2 !== null) {
result1 = [result1, result2];
} else {
result1 = null;
pos = pos0;
}
} else {
result1 = null;
pos = pos0;
}
while (result1 !== null) {
result0.push(result1);
pos0 = pos;
if (input.charCodeAt(pos) === 59) {
result1 = ";";
pos++;
} else {
result1 = null;
if (reportFailures === 0) {
matchFailed("\";\"");
}
}
if (result1 !== null) {
result2 = parse_uri_parameter();
if (result2 !== null) {
result1 = [result1, result2];
} else {
result1 = null;
pos = pos0;
}
} else {
result1 = null;
pos = pos0;
}
}
return result0;
}
function parse_uri_parameter() {
var result0;
result0 = parse_transport_param();
if (result0 === null) {
result0 = parse_user_param();
if (result0 === null) {
result0 = parse_method_param();
if (result0 === null) {
result0 = parse_ttl_param();
if (result0 === null) {
result0 = parse_maddr_param();
if (result0 === null) {
result0 = parse_lr_param();
if (result0 === null) {
result0 = parse_other_param();
}
}
}
}
}
}
return result0;
}
function parse_transport_param() {
var result0, result1;
var pos0, pos1;
pos0 = pos;
pos1 = pos;
if (input.substr(pos, 10).toLowerCase() === "transport=") {
result0 = input.substr(pos, 10);
pos += 10;
} else {
result0 = null;
if (reportFailures === 0) {
matchFailed("\"transport=\"");
}
}
if (result0 !== null) {
if (input.substr(pos, 3).toLowerCase() === "udp") {
result1 = input.substr(pos, 3);
pos += 3;
} else {
result1 = null;
if (reportFailures === 0) {
matchFailed("\"udp\"");
}
}
if (result1 === null) {
if (input.substr(pos, 3).toLowerCase() === "tcp") {
result1 = input.substr(pos, 3);
pos += 3;
} else {
result1 = null;
if (reportFailures === 0) {
matchFailed("\"tcp\"");
}
}
if (result1 === null) {
if (input.substr(pos, 4).toLowerCase() === "sctp") {
result1 = input.substr(pos, 4);
pos += 4;
} else {
result1 = null;
if (reportFailures === 0) {
matchFailed("\"sctp\"");
}
}
if (result1 === null) {
if (input.substr(pos, 3).toLowerCase() === "tls") {
result1 = input.substr(pos, 3);
pos += 3;
} else {
result1 = null;
if (reportFailures === 0) {
matchFailed("\"tls\"");
}
}
if (result1 === null) {
result1 = parse_token();
}
}
}
}
if (result1 !== null) {
result0 = [result0, result1];
} else {
result0 = null;
pos = pos1;
}
} else {
result0 = null;
pos = pos1;
}
if (result0 !== null) {
result0 = function (offset, transport) {
if (!data.uri_params) data.uri_params = {};
data.uri_params['transport'] = transport.toLowerCase();
}(pos0, result0[1]);
}
if (result0 === null) {
pos = pos0;
}
return result0;
}
function parse_user_param() {
var result0, result1;
var pos0, pos1;
pos0 = pos;
pos1 = pos;
if (input.substr(pos, 5).toLowerCase() === "user=") {
result0 = input.substr(pos, 5);
pos += 5;
} else {
result0 = null;
if (reportFailures === 0) {
matchFailed("\"user=\"");
}
}
if (result0 !== null) {
if (input.substr(pos, 5).toLowerCase() === "phone") {
result1 = input.substr(pos, 5);
pos += 5;
} else {
result1 = null;
if (reportFailures === 0) {
matchFailed("\"phone\"");
}
}
if (result1 === null) {
if (input.substr(pos, 2).toLowerCase() === "ip") {
result1 = input.substr(pos, 2);
pos += 2;
} else {
result1 = null;
if (reportFailures === 0) {
matchFailed("\"ip\"");
}
}
if (result1 === null) {
result1 = parse_token();
}
}
if (result1 !== null) {
result0 = [result0, result1];
} else {
result0 = null;
pos = pos1;
}
} else {
result0 = null;
pos = pos1;
}
if (result0 !== null) {
result0 = function (offset, user) {
if (!data.uri_params) data.uri_params = {};
data.uri_params['user'] = user.toLowerCase();
}(pos0, result0[1]);
}
if (result0 === null) {
pos = pos0;
}
return result0;
}
function parse_method_param() {
var result0, result1;
var pos0, pos1;
pos0 = pos;
pos1 = pos;
if (input.substr(pos, 7).toLowerCase() === "method=") {
result0 = input.substr(pos, 7);
pos += 7;
} else {
result0 = null;
if (reportFailures === 0) {
matchFailed("\"method=\"");
}
}
if (result0 !== null) {
result1 = parse_Method();
if (result1 !== null) {
result0 = [result0, result1];
} else {
result0 = null;
pos = pos1;
}
} else {
result0 = null;
pos = pos1;
}
if (result0 !== null) {
result0 = function (offset, method) {
if (!data.uri_params) data.uri_params = {};
data.uri_params['method'] = method;
}(pos0, result0[1]);
}
if (result0 === null) {
pos = pos0;
}
return result0;
}
function parse_ttl_param() {
var result0, result1;
var pos0, pos1;
pos0 = pos;
pos1 = pos;
if (input.substr(pos, 4).toLowerCase() === "ttl=") {
result0 = input.substr(pos, 4);
pos += 4;
} else {
result0 = null;
if (reportFailures === 0) {
matchFailed("\"ttl=\"");
}
}
if (result0 !== null) {
result1 = parse_ttl();
if (result1 !== null) {
result0 = [result0, result1];
} else {
result0 = null;
pos = pos1;
}
} else {
result0 = null;
pos = pos1;
}
if (result0 !== null) {
result0 = function (offset, ttl) {
if (!data.params) data.params = {};
data.params['ttl'] = ttl;
}(pos0, result0[1]);
}
if (result0 === null) {
pos = pos0;
}
return result0;
}
function parse_maddr_param() {
var result0, result1;
var pos0, pos1;
pos0 = pos;
pos1 = pos;
if (input.substr(pos, 6).toLowerCase() === "maddr=") {
result0 = input.substr(pos, 6);
pos += 6;
} else {
result0 = null;
if (reportFailures === 0) {
matchFailed("\"maddr=\"");
}
}
if (result0 !== null) {
result1 = parse_host();
if (result1 !== null) {
result0 = [result0, result1];
} else {
result0 = null;
pos = pos1;
}
} else {
result0 = null;
pos = pos1;
}
if (result0 !== null) {
result0 = function (offset, maddr) {
if (!data.uri_params) data.uri_params = {};
data.uri_params['maddr'] = maddr;
}(pos0, result0[1]);
}
if (result0 === null) {
pos = pos0;
}
return result0;
}
function parse_lr_param() {
var result0, result1, result2;
var pos0, pos1, pos2;
pos0 = pos;
pos1 = pos;
if (input.substr(pos, 2).toLowerCase() === "lr") {
result0 = input.substr(pos, 2);
pos += 2;
} else {
result0 = null;
if (reportFailures === 0) {
matchFailed("\"lr\"");
}
}
if (result0 !== null) {
pos2 = pos;
if (input.charCodeAt(pos) === 61) {
result1 = "=";
pos++;
} else {
result1 = null;
if (reportFailures === 0) {
matchFailed("\"=\"");
}
}
if (result1 !== null) {
result2 = parse_token();
if (result2 !== null) {
result1 = [result1, result2];
} else {
result1 = null;
pos = pos2;
}
} else {
result1 = null;
pos = pos2;
}
result1 = result1 !== null ? result1 : "";
if (result1 !== null) {
result0 = [result0, result1];
} else {
result0 = null;
pos = pos1;
}
} else {
result0 = null;
pos = pos1;
}
if (result0 !== null) {
result0 = function (offset) {
if (!data.uri_params) data.uri_params = {};
data.uri_params['lr'] = undefined;
}(pos0);
}
if (result0 === null) {
pos = pos0;
}
return result0;
}
function parse_other_param() {
var result0, result1, result2;
var pos0, pos1, pos2;
pos0 = pos;
pos1 = pos;
result0 = parse_pname();
if (result0 !== null) {
pos2 = pos;
if (input.charCodeAt(pos) === 61) {
result1 = "=";
pos++;
} else {
result1 = null;
if (reportFailures === 0) {
matchFailed("\"=\"");
}
}
if (result1 !== null) {
result2 = parse_pvalue();
if (result2 !== null) {
result1 = [result1, result2];
} else {
result1 = null;
pos = pos2;
}
} else {
result1 = null;
pos = pos2;
}
result1 = result1 !== null ? result1 : "";
if (result1 !== null) {
result0 = [result0, result1];
} else {
result0 = null;
pos = pos1;
}
} else {
result0 = null;
pos = pos1;
}
if (result0 !== null) {
result0 = function (offset, param, value) {
if (!data.uri_params) data.uri_params = {};
if (typeof value === 'undefined') {
value = undefined;
} else {
value = value[1];
}
data.uri_params[param.toLowerCase()] = value;
}(pos0, result0[0], result0[1]);
}
if (result0 === null) {
pos = pos0;
}
return result0;
}
function parse_pname() {
var result0, result1;
var pos0;
pos0 = pos;
result1 = parse_paramchar();
if (result1 !== null) {
result0 = [];
while (result1 !== null) {
result0.push(result1);
result1 = parse_paramchar();
}
} else {
result0 = null;
}
if (result0 !== null) {
result0 = function (offset, pname) {
return pname.join('');
}(pos0, result0);
}
if (result0 === null) {
pos = pos0;
}
return result0;
}
function parse_pvalue() {
var result0, result1;
var pos0;
pos0 = pos;
result1 = parse_paramchar();
if (result1 !== null) {
result0 = [];
while (result1 !== null) {
result0.push(result1);
result1 = parse_paramchar();
}
} else {
result0 = null;
}
if (result0 !== null) {
result0 = function (offset, pvalue) {
return pvalue.join('');
}(pos0, result0);
}
if (result0 === null) {
pos = pos0;
}
return result0;
}
function parse_paramchar() {
var result0;
result0 = parse_param_unreserved();
if (result0 === null) {
result0 = parse_unreserved();
if (result0 === null) {
result0 = parse_escaped();
}
}
return result0;
}
function parse_param_unreserved() {
var result0;
if (input.charCodeAt(pos) === 91) {
result0 = "[";
pos++;
} else {
result0 = null;
if (reportFailures === 0) {
matchFailed("\"[\"");
}
}
if (result0 === null) {
if (input.charCodeAt(pos) === 93) {
result0 = "]";
pos++;
} else {
result0 = null;
if (reportFailures === 0) {
matchFailed("\"]\"");
}
}
if (result0 === null) {
if (input.charCodeAt(pos) === 47) {
result0 = "/";
pos++;
} else {
result0 = null;
if (reportFailures === 0) {
matchFailed("\"/\"");
}
}
if (result0 === null) {
if (input.charCodeAt(pos) === 58) {
result0 = ":";
pos++;
} else {
result0 = null;
if (reportFailures === 0) {
matchFailed("\":\"");
}
}
if (result0 === null) {
if (input.charCodeAt(pos) === 38) {
result0 = "&";
pos++;
} else {
result0 = null;
if (reportFailures === 0) {
matchFailed("\"&\"");
}
}
if (result0 === null) {
if (input.charCodeAt(pos) === 43) {
result0 = "+";
pos++;
} else {
result0 = null;
if (reportFailures === 0) {
matchFailed("\"+\"");
}
}
if (result0 === null) {
if (input.charCodeAt(pos) === 36) {
result0 = "$";
pos++;
} else {
result0 = null;
if (reportFailures === 0) {
matchFailed("\"$\"");
}
}
}
}
}
}
}
}
return result0;
}
function parse_headers() {
var result0, result1, result2, result3, result4;
var pos0, pos1;
pos0 = pos;
if (input.charCodeAt(pos) === 63) {
result0 = "?";
pos++;
} else {
result0 = null;
if (reportFailures === 0) {
matchFailed("\"?\"");
}
}
if (result0 !== null) {
result1 = parse_header();
if (result1 !== null) {
result2 = [];
pos1 = pos;
if (input.charCodeAt(pos) === 38) {
result3 = "&";
pos++;
} else {
result3 = null;
if (reportFailures === 0) {
matchFailed("\"&\"");
}
}
if (result3 !== null) {
result4 = parse_header();
if (result4 !== null) {
result3 = [result3, result4];
} else {
result3 = null;
pos = pos1;
}
} else {
result3 = null;
pos = pos1;
}
while (result3 !== null) {
result2.push(result3);
pos1 = pos;
if (input.charCodeAt(pos) === 38) {
result3 = "&";
pos++;
} else {
result3 = null;
if (reportFailures === 0) {
matchFailed("\"&\"");
}
}
if (result3 !== null) {
result4 = parse_header();
if (result4 !== null) {
result3 = [result3, result4];
} else {
result3 = null;
pos = pos1;
}
} else {
result3 = null;
pos = pos1;
}
}
if (result2 !== null) {
result0 = [result0, result1, result2];
} else {
result0 = null;
pos = pos0;
}
} else {
result0 = null;
pos = pos0;
}
} else {
result0 = null;
pos = pos0;
}
return result0;
}
function parse_header() {
var result0, result1, result2;
var pos0, pos1;
pos0 = pos;
pos1 = pos;
result0 = parse_hname();
if (result0 !== null) {
if (input.charCodeAt(pos) === 61) {
result1 = "=";
pos++;
} else {
result1 = null;
if (reportFailures === 0) {
matchFailed("\"=\"");
}
}
if (result1 !== null) {
result2 = parse_hvalue();
if (result2 !== null) {
result0 = [result0, result1, result2];
} else {
result0 = null;
pos = pos1;
}
} else {
result0 = null;
pos = pos1;
}
} else {
result0 = null;
pos = pos1;
}
if (result0 !== null) {
result0 = function (offset, hname, hvalue) {
hname = hname.join('').toLowerCase();
hvalue = hvalue.join('');
if (!data.uri_headers) data.uri_headers = {};
if (!data.uri_headers[hname]) {
data.uri_headers[hname] = [hvalue];
} else {
data.uri_headers[hname].push(hvalue);
}
}(pos0, result0[0], result0[2]);
}
if (result0 === null) {
pos = pos0;
}
return result0;
}
function parse_hname() {
var result0, result1;
result1 = parse_hnv_unreserved();
if (result1 === null) {
result1 = parse_unreserved();
if (result1 === null) {
result1 = parse_escaped();
}
}
if (result1 !== null) {
result0 = [];
while (result1 !== null) {
result0.push(result1);
result1 = parse_hnv_unreserved();
if (result1 === null) {
result1 = parse_unreserved();
if (result1 === null) {
result1 = parse_escaped();
}
}
}
} else {
result0 = null;
}
return result0;
}
function parse_hvalue() {
var result0, result1;
result0 = [];
result1 = parse_hnv_unreserved();
if (result1 === null) {
result1 = parse_unreserved();
if (result1 === null) {
result1 = parse_escaped();
}
}
while (result1 !== null) {
result0.push(result1);
result1 = parse_hnv_unreserved();
if (result1 === null) {
result1 = parse_unreserved();
if (result1 === null) {
result1 = parse_escaped();
}
}
}
return result0;
}
function parse_hnv_unreserved() {
var result0;
if (input.charCodeAt(pos) === 91) {
result0 = "[";
pos++;
} else {
result0 = null;
if (reportFailures === 0) {
matchFailed("\"[\"");
}
}
if (result0 === null) {
if (input.charCodeAt(pos) === 93) {
result0 = "]";
pos++;
} else {
result0 = null;
if (reportFailures === 0) {
matchFailed("\"]\"");
}
}
if (result0 === null) {
if (input.charCodeAt(pos) === 47) {
result0 = "/";
pos++;
} else {
result0 = null;
if (reportFailures === 0) {
matchFailed("\"/\"");
}
}
if (result0 === null) {
if (input.charCodeAt(pos) === 63) {
result0 = "?";
pos++;
} else {
result0 = null;
if (reportFailures === 0) {
matchFailed("\"?\"");
}
}
if (result0 === null) {
if (input.charCodeAt(pos) === 58) {
result0 = ":";
pos++;
} else {
result0 = null;
if (reportFailures === 0) {
matchFailed("\":\"");
}
}
if (result0 === null) {
if (input.charCodeAt(pos) === 43) {
result0 = "+";
pos++;
} else {
result0 = null;
if (reportFailures === 0) {
matchFailed("\"+\"");
}
}
if (result0 === null) {
if (input.charCodeAt(pos) === 36) {
result0 = "$";
pos++;
} else {
result0 = null;
if (reportFailures === 0) {
matchFailed("\"$\"");
}
}
}
}
}
}
}
}
return result0;
}
function parse_Request_Response() {
var result0;
result0 = parse_Status_Line();
if (result0 === null) {
result0 = parse_Request_Line();
}
return result0;
}
function parse_Request_Line() {
var result0, result1, result2, result3, result4;
var pos0;
pos0 = pos;
result0 = parse_Method();
if (result0 !== null) {
result1 = parse_SP();
if (result1 !== null) {
result2 = parse_Request_URI();
if (result2 !== null) {
result3 = parse_SP();
if (result3 !== null) {
result4 = parse_SIP_Version();
if (result4 !== null) {
result0 = [result0, result1, result2, result3, result4];
} else {
result0 = null;
pos = pos0;
}
} else {
result0 = null;
pos = pos0;
}
} else {
result0 = null;
pos = pos0;
}
} else {
result0 = null;
pos = pos0;
}
} else {
result0 = null;
pos = pos0;
}
return result0;
}
function parse_Request_URI() {
var result0;
result0 = parse_SIP_URI();
if (result0 === null) {
result0 = parse_absoluteURI();
}
return result0;
}
function parse_absoluteURI() {
var result0, result1, result2;
var pos0;
pos0 = pos;
result0 = parse_scheme();
if (result0 !== null) {
if (input.charCodeAt(pos) === 58) {
result1 = ":";
pos++;
} else {
result1 = null;
if (reportFailures === 0) {
matchFailed("\":\"");
}
}
if (result1 !== null) {
result2 = parse_hier_part();
if (result2 === null) {
result2 = parse_opaque_part();
}
if (result2 !== null) {
result0 = [result0, result1, result2];
} else {
result0 = null;
pos = pos0;
}
} else {
result0 = null;
pos = pos0;
}
} else {
result0 = null;
pos = pos0;
}
return result0;
}
function parse_hier_part() {
var result0, result1, result2;
var pos0, pos1;
pos0 = pos;
result0 = parse_net_path();
if (result0 === null) {
result0 = parse_abs_path();
}
if (result0 !== null) {
pos1 = pos;
if (input.charCodeAt(pos) === 63) {
result1 = "?";
pos++;
} else {
result1 = null;
if (reportFailures === 0) {
matchFailed("\"?\"");
}
}
if (result1 !== null) {
result2 = parse_query();
if (result2 !== null) {
result1 = [result1, result2];
} else {
result1 = null;
pos = pos1;
}
} else {
result1 = null;
pos = pos1;
}
result1 = result1 !== null ? result1 : "";
if (result1 !== null) {
result0 = [result0, result1];
} else {
result0 = null;
pos = pos0;
}
} else {
result0 = null;
pos = pos0;
}
return result0;
}
function parse_net_path() {
var result0, result1, result2;
var pos0;
pos0 = pos;
if (input.substr(pos, 2) === "//") {
result0 = "//";
pos += 2;
} else {
result0 = null;
if (reportFailures === 0) {
matchFailed("\"//\"");
}
}
if (result0 !== null) {
result1 = parse_authority();
if (result1 !== null) {
result2 = parse_abs_path();
result2 = result2 !== null ? result2 : "";
if (result2 !== null) {
result0 = [result0, result1, result2];
} else {
result0 = null;
pos = pos0;
}
} else {
result0 = null;
pos = pos0;
}
} else {
result0 = null;
pos = pos0;
}
return result0;
}
function parse_abs_path() {
var result0, result1;
var pos0;
pos0 = pos;
if (input.charCodeAt(pos) === 47) {
result0 = "/";
pos++;
} else {
result0 = null;
if (reportFailures === 0) {
matchFailed("\"/\"");
}
}
if (result0 !== null) {
result1 = parse_path_segments();
if (result1 !== null) {
result0 = [result0, result1];
} else {
result0 = null;
pos = pos0;
}
} else {
result0 = null;
pos = pos0;
}
return result0;
}
function parse_opaque_part() {
var result0, result1, result2;
var pos0;
pos0 = pos;
result0 = parse_uric_no_slash();
if (result0 !== null) {
result1 = [];
result2 = parse_uric();
while (result2 !== null) {
result1.push(result2);
result2 = parse_uric();
}
if (result1 !== null) {
result0 = [result0, result1];
} else {
result0 = null;
pos = pos0;
}
} else {
result0 = null;
pos = pos0;
}
return result0;
}
function parse_uric() {
var result0;
result0 = parse_reserved();
if (result0 === null) {
result0 = parse_unreserved();
if (result0 === null) {
result0 = parse_escaped();
}
}
return result0;
}
function parse_uric_no_slash() {
var result0;
result0 = parse_unreserved();
if (result0 === null) {
result0 = parse_escaped();
if (result0 === null) {
if (input.charCodeAt(pos) === 59) {
result0 = ";";
pos++;
} else {
result0 = null;
if (reportFailures === 0) {
matchFailed("\";\"");
}
}
if (result0 === null) {
if (input.charCodeAt(pos) === 63) {
result0 = "?";
pos++;
} else {
result0 = null;
if (reportFailures === 0) {
matchFailed("\"?\"");
}
}
if (result0 === null) {
if (input.charCodeAt(pos) === 58) {
result0 = ":";
pos++;
} else {
result0 = null;
if (reportFailures === 0) {
matchFailed("\":\"");
}
}
if (result0 === null) {
if (input.charCodeAt(pos) === 64) {
result0 = "@";
pos++;
} else {
result0 = null;
if (reportFailures === 0) {
matchFailed("\"@\"");
}
}
if (result0 === null) {
if (input.charCodeAt(pos) === 38) {
result0 = "&";
pos++;
} else {
result0 = null;
if (reportFailures === 0) {
matchFailed("\"&\"");
}
}
if (result0 === null) {
if (input.charCodeAt(pos) === 61) {
result0 = "=";
pos++;
} else {
result0 = null;
if (reportFailures === 0) {
matchFailed("\"=\"");
}
}
if (result0 === null) {
if (input.charCodeAt(pos) === 43) {
result0 = "+";
pos++;
} else {
result0 = null;
if (reportFailures === 0) {
matchFailed("\"+\"");
}
}
if (result0 === null) {
if (input.charCodeAt(pos) === 36) {
result0 = "$";
pos++;
} else {
result0 = null;
if (reportFailures === 0) {
matchFailed("\"$\"");
}
}
if (result0 === null) {
if (input.charCodeAt(pos) === 44) {
result0 = ",";
pos++;
} else {
result0 = null;
if (reportFailures === 0) {
matchFailed("\",\"");
}
}
}
}
}
}
}
}
}
}
}
}
return result0;
}
function parse_path_segments() {
var result0, result1, result2, result3;
var pos0, pos1;
pos0 = pos;
result0 = parse_segment();
if (result0 !== null) {
result1 = [];
pos1 = pos;
if (input.charCodeAt(pos) === 47) {
result2 = "/";
pos++;
} else {
result2 = null;
if (reportFailures === 0) {
matchFailed("\"/\"");
}
}
if (result2 !== null) {
result3 = parse_segment();
if (result3 !== null) {
result2 = [result2, result3];
} else {
result2 = null;
pos = pos1;
}
} else {
result2 = null;
pos = pos1;
}
while (result2 !== null) {
result1.push(result2);
pos1 = pos;
if (input.charCodeAt(pos) === 47) {
result2 = "/";
pos++;
} else {
result2 = null;
if (reportFailures === 0) {
matchFailed("\"/\"");
}
}
if (result2 !== null) {
result3 = parse_segment();
if (result3 !== null) {
result2 = [result2, result3];
} else {
result2 = null;
pos = pos1;
}
} else {
result2 = null;
pos = pos1;
}
}
if (result1 !== null) {
result0 = [result0, result1];
} else {
result0 = null;
pos = pos0;
}
} else {
result0 = null;
pos = pos0;
}
return result0;
}
function parse_segment() {
var result0, result1, result2, result3;
var pos0, pos1;
pos0 = pos;
result0 = [];
result1 = parse_pchar();
while (result1 !== null) {
result0.push(result1);
result1 = parse_pchar();
}
if (result0 !== null) {
result1 = [];
pos1 = pos;
if (input.charCodeAt(pos) === 59) {
result2 = ";";
pos++;
} else {
result2 = null;
if (reportFailures === 0) {
matchFailed("\";\"");
}
}
if (result2 !== null) {
result3 = parse_param();
if (result3 !== null) {
result2 = [result2, result3];
} else {
result2 = null;
pos = pos1;
}
} else {
result2 = null;
pos = pos1;
}
while (result2 !== null) {
result1.push(result2);
pos1 = pos;
if (input.charCodeAt(pos) === 59) {
result2 = ";";
pos++;
} else {
result2 = null;
if (reportFailures === 0) {
matchFailed("\";\"");
}
}
if (result2 !== null) {
result3 = parse_param();
if (result3 !== null) {
result2 = [result2, result3];
} else {
result2 = null;
pos = pos1;
}
} else {
result2 = null;
pos = pos1;
}
}
if (result1 !== null) {
result0 = [result0, result1];
} else {
result0 = null;
pos = pos0;
}
} else {
result0 = null;
pos = pos0;
}
return result0;
}
function parse_param() {
var result0, result1;
result0 = [];
result1 = parse_pchar();
while (result1 !== null) {
result0.push(result1);
result1 = parse_pchar();
}
return result0;
}
function parse_pchar() {
var result0;
result0 = parse_unreserved();
if (result0 === null) {
result0 = parse_escaped();
if (result0 === null) {
if (input.charCodeAt(pos) === 58) {
result0 = ":";
pos++;
} else {
result0 = null;
if (reportFailures === 0) {
matchFailed("\":\"");
}
}
if (result0 === null) {
if (input.charCodeAt(pos) === 64) {
result0 = "@";
pos++;
} else {
result0 = null;
if (reportFailures === 0) {
matchFailed("\"@\"");
}
}
if (result0 === null) {
if (input.charCodeAt(pos) === 38) {
result0 = "&";
pos++;
} else {
result0 = null;
if (reportFailures === 0) {
matchFailed("\"&\"");
}
}
if (result0 === null) {
if (input.charCodeAt(pos) === 61) {
result0 = "=";
pos++;
} else {
result0 = null;
if (reportFailures === 0) {
matchFailed("\"=\"");
}
}
if (result0 === null) {
if (input.charCodeAt(pos) === 43) {
result0 = "+";
pos++;
} else {
result0 = null;
if (reportFailures === 0) {
matchFailed("\"+\"");
}
}
if (result0 === null) {
if (input.charCodeAt(pos) === 36) {
result0 = "$";
pos++;
} else {
result0 = null;
if (reportFailures === 0) {
matchFailed("\"$\"");
}
}
if (result0 === null) {
if (input.charCodeAt(pos) === 44) {
result0 = ",";
pos++;
} else {
result0 = null;
if (reportFailures === 0) {
matchFailed("\",\"");
}
}
}
}
}
}
}
}
}
}
return result0;
}
function parse_scheme() {
var result0, result1, result2;
var pos0, pos1;
pos0 = pos;
pos1 = pos;
result0 = parse_ALPHA();
if (result0 !== null) {
result1 = [];
result2 = parse_ALPHA();
if (result2 === null) {
result2 = parse_DIGIT();
if (result2 === null) {
if (input.charCodeAt(pos) === 43) {
result2 = "+";
pos++;
} else {
result2 = null;
if (reportFailures === 0) {
matchFailed("\"+\"");
}
}
if (result2 === null) {
if (input.charCodeAt(pos) === 45) {
result2 = "-";
pos++;
} else {
result2 = null;
if (reportFailures === 0) {
matchFailed("\"-\"");
}
}
if (result2 === null) {
if (input.charCodeAt(pos) === 46) {
result2 = ".";
pos++;
} else {
result2 = null;
if (reportFailures === 0) {
matchFailed("\".\"");
}
}
}
}
}
}
while (result2 !== null) {
result1.push(result2);
result2 = parse_ALPHA();
if (result2 === null) {
result2 = parse_DIGIT();
if (result2 === null) {
if (input.charCodeAt(pos) === 43) {
result2 = "+";
pos++;
} else {
result2 = null;
if (reportFailures === 0) {
matchFailed("\"+\"");
}
}
if (result2 === null) {
if (input.charCodeAt(pos) === 45) {
result2 = "-";
pos++;
} else {
result2 = null;
if (reportFailures === 0) {
matchFailed("\"-\"");
}
}
if (result2 === null) {
if (input.charCodeAt(pos) === 46) {
result2 = ".";
pos++;
} else {
result2 = null;
if (reportFailures === 0) {
matchFailed("\".\"");
}
}
}
}
}
}
}
if (result1 !== null) {
result0 = [result0, result1];
} else {
result0 = null;
pos = pos1;
}
} else {
result0 = null;
pos = pos1;
}
if (result0 !== null) {
result0 = function (offset) {
data.scheme = input.substring(pos, offset);
}(pos0);
}
if (result0 === null) {
pos = pos0;
}
return result0;
}
function parse_authority() {
var result0;
result0 = parse_srvr();
if (result0 === null) {
result0 = parse_reg_name();
}
return result0;
}
function parse_srvr() {
var result0, result1;
var pos0, pos1;
pos0 = pos;
pos1 = pos;
result0 = parse_userinfo();
if (result0 !== null) {
if (input.charCodeAt(pos) === 64) {
result1 = "@";
pos++;
} else {
result1 = null;
if (reportFailures === 0) {
matchFailed("\"@\"");
}
}
if (result1 !== null) {
result0 = [result0, result1];
} else {
result0 = null;
pos = pos1;
}
} else {
result0 = null;
pos = pos1;
}
result0 = result0 !== null ? result0 : "";
if (result0 !== null) {
result1 = parse_hostport();
if (result1 !== null) {
result0 = [result0, result1];
} else {
result0 = null;
pos = pos0;
}
} else {
result0 = null;
pos = pos0;
}
result0 = result0 !== null ? result0 : "";
return result0;
}
function parse_reg_name() {
var result0, result1;
result1 = parse_unreserved();
if (result1 === null) {
result1 = parse_escaped();
if (result1 === null) {
if (input.charCodeAt(pos) === 36) {
result1 = "$";
pos++;
} else {
result1 = null;
if (reportFailures === 0) {
matchFailed("\"$\"");
}
}
if (result1 === null) {
if (input.charCodeAt(pos) === 44) {
result1 = ",";
pos++;
} else {
result1 = null;
if (reportFailures === 0) {
matchFailed("\",\"");
}
}
if (result1 === null) {
if (input.charCodeAt(pos) === 59) {
result1 = ";";
pos++;
} else {
result1 = null;
if (reportFailures === 0) {
matchFailed("\";\"");
}
}
if (result1 === null) {
if (input.charCodeAt(pos) === 58) {
result1 = ":";
pos++;
} else {
result1 = null;
if (reportFailures === 0) {
matchFailed("\":\"");
}
}
if (result1 === null) {
if (input.charCodeAt(pos) === 64) {
result1 = "@";
pos++;
} else {
result1 = null;
if (reportFailures === 0) {
matchFailed("\"@\"");
}
}
if (result1 === null) {
if (input.charCodeAt(pos) === 38) {
result1 = "&";
pos++;
} else {
result1 = null;
if (reportFailures === 0) {
matchFailed("\"&\"");
}
}
if (result1 === null) {
if (input.charCodeAt(pos) === 61) {
result1 = "=";
pos++;
} else {
result1 = null;
if (reportFailures === 0) {
matchFailed("\"=\"");
}
}
if (result1 === null) {
if (input.charCodeAt(pos) === 43) {
result1 = "+";
pos++;
} else {
result1 = null;
if (reportFailures === 0) {
matchFailed("\"+\"");
}
}
}
}
}
}
}
}
}
}
}
if (result1 !== null) {
result0 = [];
while (result1 !== null) {
result0.push(result1);
result1 = parse_unreserved();
if (result1 === null) {
result1 = parse_escaped();
if (result1 === null) {
if (input.charCodeAt(pos) === 36) {
result1 = "$";
pos++;
} else {
result1 = null;
if (reportFailures === 0) {
matchFailed("\"$\"");
}
}
if (result1 === null) {
if (input.charCodeAt(pos) === 44) {
result1 = ",";
pos++;
} else {
result1 = null;
if (reportFailures === 0) {
matchFailed("\",\"");
}
}
if (result1 === null) {
if (input.charCodeAt(pos) === 59) {
result1 = ";";
pos++;
} else {
result1 = null;
if (reportFailures === 0) {
matchFailed("\";\"");
}
}
if (result1 === null) {
if (input.charCodeAt(pos) === 58) {
result1 = ":";
pos++;
} else {
result1 = null;
if (reportFailures === 0) {
matchFailed("\":\"");
}
}
if (result1 === null) {
if (input.charCodeAt(pos) === 64) {
result1 = "@";
pos++;
} else {
result1 = null;
if (reportFailures === 0) {
matchFailed("\"@\"");
}
}
if (result1 === null) {
if (input.charCodeAt(pos) === 38) {
result1 = "&";
pos++;
} else {
result1 = null;
if (reportFailures === 0) {
matchFailed("\"&\"");
}
}
if (result1 === null) {
if (input.charCodeAt(pos) === 61) {
result1 = "=";
pos++;
} else {
result1 = null;
if (reportFailures === 0) {
matchFailed("\"=\"");
}
}
if (result1 === null) {
if (input.charCodeAt(pos) === 43) {
result1 = "+";
pos++;
} else {
result1 = null;
if (reportFailures === 0) {
matchFailed("\"+\"");
}
}
}
}
}
}
}
}
}
}
}
}
} else {
result0 = null;
}
return result0;
}
function parse_query() {
var result0, result1;
result0 = [];
result1 = parse_uric();
while (result1 !== null) {
result0.push(result1);
result1 = parse_uric();
}
return result0;
}
function parse_SIP_Version() {
var result0, result1, result2, result3, result4, result5;
var pos0, pos1;
pos0 = pos;
pos1 = pos;
if (input.substr(pos, 3).toLowerCase() === "sip") {
result0 = input.substr(pos, 3);
pos += 3;
} else {
result0 = null;
if (reportFailures === 0) {
matchFailed("\"SIP\"");
}
}
if (result0 !== null) {
if (input.charCodeAt(pos) === 47) {
result1 = "/";
pos++;
} else {
result1 = null;
if (reportFailures === 0) {
matchFailed("\"/\"");
}
}
if (result1 !== null) {
result3 = parse_DIGIT();
if (result3 !== null) {
result2 = [];
while (result3 !== null) {
result2.push(result3);
result3 = parse_DIGIT();
}
} else {
result2 = null;
}
if (result2 !== null) {
if (input.charCodeAt(pos) === 46) {
result3 = ".";
pos++;
} else {
result3 = null;
if (reportFailures === 0) {
matchFailed("\".\"");
}
}
if (result3 !== null) {
result5 = parse_DIGIT();
if (result5 !== null) {
result4 = [];
while (result5 !== null) {
result4.push(result5);
result5 = parse_DIGIT();
}
} else {
result4 = null;
}
if (result4 !== null) {
result0 = [result0, result1, result2, result3, result4];
} else {
result0 = null;
pos = pos1;
}
} else {
result0 = null;
pos = pos1;
}
} else {
result0 = null;
pos = pos1;
}
} else {
result0 = null;
pos = pos1;
}
} else {
result0 = null;
pos = pos1;
}
if (result0 !== null) {
result0 = function (offset) {
data.sip_version = input.substring(pos, offset);
}(pos0);
}
if (result0 === null) {
pos = pos0;
}
return result0;
}
function parse_INVITEm() {
var result0;
if (input.substr(pos, 6) === "INVITE") {
result0 = "INVITE";
pos += 6;
} else {
result0 = null;
if (reportFailures === 0) {
matchFailed("\"INVITE\"");
}
}
return result0;
}
function parse_ACKm() {
var result0;
if (input.substr(pos, 3) === "ACK") {
result0 = "ACK";
pos += 3;
} else {
result0 = null;
if (reportFailures === 0) {
matchFailed("\"ACK\"");
}
}
return result0;
}
function parse_OPTIONSm() {
var result0;
if (input.substr(pos, 7) === "OPTIONS") {
result0 = "OPTIONS";
pos += 7;
} else {
result0 = null;
if (reportFailures === 0) {
matchFailed("\"OPTIONS\"");
}
}
return result0;
}
function parse_BYEm() {
var result0;
if (input.substr(pos, 3) === "BYE") {
result0 = "BYE";
pos += 3;
} else {
result0 = null;
if (reportFailures === 0) {
matchFailed("\"BYE\"");
}
}
return result0;
}
function parse_CANCELm() {
var result0;
if (input.substr(pos, 6) === "CANCEL") {
result0 = "CANCEL";
pos += 6;
} else {
result0 = null;
if (reportFailures === 0) {
matchFailed("\"CANCEL\"");
}
}
return result0;
}
function parse_REGISTERm() {
var result0;
if (input.substr(pos, 8) === "REGISTER") {
result0 = "REGISTER";
pos += 8;
} else {
result0 = null;
if (reportFailures === 0) {
matchFailed("\"REGISTER\"");
}
}
return result0;
}
function parse_SUBSCRIBEm() {
var result0;
if (input.substr(pos, 9) === "SUBSCRIBE") {
result0 = "SUBSCRIBE";
pos += 9;
} else {
result0 = null;
if (reportFailures === 0) {
matchFailed("\"SUBSCRIBE\"");
}
}
return result0;
}
function parse_NOTIFYm() {
var result0;
if (input.substr(pos, 6) === "NOTIFY") {
result0 = "NOTIFY";
pos += 6;
} else {
result0 = null;
if (reportFailures === 0) {
matchFailed("\"NOTIFY\"");
}
}
return result0;
}
function parse_REFERm() {
var result0;
if (input.substr(pos, 5) === "REFER") {
result0 = "REFER";
pos += 5;
} else {
result0 = null;
if (reportFailures === 0) {
matchFailed("\"REFER\"");
}
}
return result0;
}
function parse_Method() {
var result0;
var pos0;
pos0 = pos;
result0 = parse_INVITEm();
if (result0 === null) {
result0 = parse_ACKm();
if (result0 === null) {
result0 = parse_OPTIONSm();
if (result0 === null) {
result0 = parse_BYEm();
if (result0 === null) {
result0 = parse_CANCELm();
if (result0 === null) {
result0 = parse_REGISTERm();
if (result0 === null) {
result0 = parse_SUBSCRIBEm();
if (result0 === null) {
result0 = parse_NOTIFYm();
if (result0 === null) {
result0 = parse_REFERm();
if (result0 === null) {
result0 = parse_token();
}
}
}
}
}
}
}
}
}
if (result0 !== null) {
result0 = function (offset) {
data.method = input.substring(pos, offset);
return data.method;
}(pos0);
}
if (result0 === null) {
pos = pos0;
}
return result0;
}
function parse_Status_Line() {
var result0, result1, result2, result3, result4;
var pos0;
pos0 = pos;
result0 = parse_SIP_Version();
if (result0 !== null) {
result1 = parse_SP();
if (result1 !== null) {
result2 = parse_Status_Code();
if (result2 !== null) {
result3 = parse_SP();
if (result3 !== null) {
result4 = parse_Reason_Phrase();
if (result4 !== null) {
result0 = [result0, result1, result2, result3, result4];
} else {
result0 = null;
pos = pos0;
}
} else {
result0 = null;
pos = pos0;
}
} else {
result0 = null;
pos = pos0;
}
} else {
result0 = null;
pos = pos0;
}
} else {
result0 = null;
pos = pos0;
}
return result0;
}
function parse_Status_Code() {
var result0;
var pos0;
pos0 = pos;
result0 = parse_extension_code();
if (result0 !== null) {
result0 = function (offset, status_code) {
data.status_code = parseInt(status_code.join(''));
}(pos0, result0);
}
if (result0 === null) {
pos = pos0;
}
return result0;
}
function parse_extension_code() {
var result0, result1, result2;
var pos0;
pos0 = pos;
result0 = parse_DIGIT();
if (result0 !== null) {
result1 = parse_DIGIT();
if (result1 !== null) {
result2 = parse_DIGIT();
if (result2 !== null) {
result0 = [result0, result1, result2];
} else {
result0 = null;
pos = pos0;
}
} else {
result0 = null;
pos = pos0;
}
} else {
result0 = null;
pos = pos0;
}
return result0;
}
function parse_Reason_Phrase() {
var result0, result1;
var pos0;
pos0 = pos;
result0 = [];
result1 = parse_reserved();
if (result1 === null) {
result1 = parse_unreserved();
if (result1 === null) {
result1 = parse_escaped();
if (result1 === null) {
result1 = parse_UTF8_NONASCII();
if (result1 === null) {
result1 = parse_UTF8_CONT();
if (result1 === null) {
result1 = parse_SP();
if (result1 === null) {
result1 = parse_HTAB();
}
}
}
}
}
}
while (result1 !== null) {
result0.push(result1);
result1 = parse_reserved();
if (result1 === null) {
result1 = parse_unreserved();
if (result1 === null) {
result1 = parse_escaped();
if (result1 === null) {
result1 = parse_UTF8_NONASCII();
if (result1 === null) {
result1 = parse_UTF8_CONT();
if (result1 === null) {
result1 = parse_SP();
if (result1 === null) {
result1 = parse_HTAB();
}
}
}
}
}
}
}
if (result0 !== null) {
result0 = function (offset) {
data.reason_phrase = input.substring(pos, offset);
}(pos0);
}
if (result0 === null) {
pos = pos0;
}
return result0;
}
function parse_Allow_Events() {
var result0, result1, result2, result3;
var pos0, pos1;
pos0 = pos;
result0 = parse_event_type();
if (result0 !== null) {
result1 = [];
pos1 = pos;
result2 = parse_COMMA();
if (result2 !== null) {
result3 = parse_event_type();
if (result3 !== null) {
result2 = [result2, result3];
} else {
result2 = null;
pos = pos1;
}
} else {
result2 = null;
pos = pos1;
}
while (result2 !== null) {
result1.push(result2);
pos1 = pos;
result2 = parse_COMMA();
if (result2 !== null) {
result3 = parse_event_type();
if (result3 !== null) {
result2 = [result2, result3];
} else {
result2 = null;
pos = pos1;
}
} else {
result2 = null;
pos = pos1;
}
}
if (result1 !== null) {
result0 = [result0, result1];
} else {
result0 = null;
pos = pos0;
}
} else {
result0 = null;
pos = pos0;
}
return result0;
}
function parse_Call_ID() {
var result0, result1, result2;
var pos0, pos1, pos2;
pos0 = pos;
pos1 = pos;
result0 = parse_word();
if (result0 !== null) {
pos2 = pos;
if (input.charCodeAt(pos) === 64) {
result1 = "@";
pos++;
} else {
result1 = null;
if (reportFailures === 0) {
matchFailed("\"@\"");
}
}
if (result1 !== null) {
result2 = parse_word();
if (result2 !== null) {
result1 = [result1, result2];
} else {
result1 = null;
pos = pos2;
}
} else {
result1 = null;
pos = pos2;
}
result1 = result1 !== null ? result1 : "";
if (result1 !== null) {
result0 = [result0, result1];
} else {
result0 = null;
pos = pos1;
}
} else {
result0 = null;
pos = pos1;
}
if (result0 !== null) {
result0 = function (offset) {
data = input.substring(pos, offset);
}(pos0);
}
if (result0 === null) {
pos = pos0;
}
return result0;
}
function parse_Contact() {
var result0, result1, result2, result3;
var pos0, pos1, pos2;
pos0 = pos;
result0 = parse_STAR();
if (result0 === null) {
pos1 = pos;
result0 = parse_contact_param();
if (result0 !== null) {
result1 = [];
pos2 = pos;
result2 = parse_COMMA();
if (result2 !== null) {
result3 = parse_contact_param();
if (result3 !== null) {
result2 = [result2, result3];
} else {
result2 = null;
pos = pos2;
}
} else {
result2 = null;
pos = pos2;
}
while (result2 !== null) {
result1.push(result2);
pos2 = pos;
result2 = parse_COMMA();
if (result2 !== null) {
result3 = parse_contact_param();
if (result3 !== null) {
result2 = [result2, result3];
} else {
result2 = null;
pos = pos2;
}
} else {
result2 = null;
pos = pos2;
}
}
if (result1 !== null) {
result0 = [result0, result1];
} else {
result0 = null;
pos = pos1;
}
} else {
result0 = null;
pos = pos1;
}
}
if (result0 !== null) {
result0 = function (offset) {
var idx, length;
length = data.multi_header.length;
for (idx = 0; idx < length; idx++) {
if (data.multi_header[idx].parsed === null) {
data = null;
break;
}
}
if (data !== null) {
data = data.multi_header;
} else {
data = -1;
}
}(pos0);
}
if (result0 === null) {
pos = pos0;
}
return result0;
}
function parse_contact_param() {
var result0, result1, result2, result3;
var pos0, pos1, pos2;
pos0 = pos;
pos1 = pos;
result0 = parse_SIP_URI_noparams();
if (result0 === null) {
result0 = parse_name_addr();
}
if (result0 !== null) {
result1 = [];
pos2 = pos;
result2 = parse_SEMI();
if (result2 !== null) {
result3 = parse_contact_params();
if (result3 !== null) {
result2 = [result2, result3];
} else {
result2 = null;
pos = pos2;
}
} else {
result2 = null;
pos = pos2;
}
while (result2 !== null) {
result1.push(result2);
pos2 = pos;
result2 = parse_SEMI();
if (result2 !== null) {
result3 = parse_contact_params();
if (result3 !== null) {
result2 = [result2, result3];
} else {
result2 = null;
pos = pos2;
}
} else {
result2 = null;
pos = pos2;
}
}
if (result1 !== null) {
result0 = [result0, result1];
} else {
result0 = null;
pos = pos1;
}
} else {
result0 = null;
pos = pos1;
}
if (result0 !== null) {
result0 = function (offset) {
var header;
if (!data.multi_header) data.multi_header = [];
try {
header = new NameAddrHeader(data.uri, data.display_name, data.params);
delete data.uri;
delete data.display_name;
delete data.params;
} catch (e) {
header = null;
}
data.multi_header.push({
'possition': pos,
'offset': offset,
'parsed': header
});
}(pos0);
}
if (result0 === null) {
pos = pos0;
}
return result0;
}
function parse_name_addr() {
var result0, result1, result2, result3;
var pos0;
pos0 = pos;
result0 = parse_display_name();
result0 = result0 !== null ? result0 : "";
if (result0 !== null) {
result1 = parse_LAQUOT();
if (result1 !== null) {
result2 = parse_SIP_URI();
if (result2 !== null) {
result3 = parse_RAQUOT();
if (result3 !== null) {
result0 = [result0, result1, result2, result3];
} else {
result0 = null;
pos = pos0;
}
} else {
result0 = null;
pos = pos0;
}
} else {
result0 = null;
pos = pos0;
}
} else {
result0 = null;
pos = pos0;
}
return result0;
}
function parse_display_name() {
var result0, result1, result2, result3;
var pos0, pos1, pos2;
pos0 = pos;
pos1 = pos;
result0 = parse_token();
if (result0 !== null) {
result1 = [];
pos2 = pos;
result2 = parse_LWS();
if (result2 !== null) {
result3 = parse_token();
if (result3 !== null) {
result2 = [result2, result3];
} else {
result2 = null;
pos = pos2;
}
} else {
result2 = null;
pos = pos2;
}
while (result2 !== null) {
result1.push(result2);
pos2 = pos;
result2 = parse_LWS();
if (result2 !== null) {
result3 = parse_token();
if (result3 !== null) {
result2 = [result2, result3];
} else {
result2 = null;
pos = pos2;
}
} else {
result2 = null;
pos = pos2;
}
}
if (result1 !== null) {
result0 = [result0, result1];
} else {
result0 = null;
pos = pos1;
}
} else {
result0 = null;
pos = pos1;
}
if (result0 === null) {
result0 = parse_quoted_string_clean();
}
if (result0 !== null) {
result0 = function (offset, display_name) {
if (typeof display_name === 'string') {
// quoted_string_clean
data.display_name = display_name;
} else {
// token ( LWS token )*
data.display_name = display_name[1].reduce(function (acc, cur) {
return acc + cur[0] + cur[1];
}, display_name[0]);
}
}(pos0, result0);
}
if (result0 === null) {
pos = pos0;
}
return result0;
}
function parse_contact_params() {
var result0;
result0 = parse_c_p_q();
if (result0 === null) {
result0 = parse_c_p_expires();
if (result0 === null) {
result0 = parse_generic_param();
}
}
return result0;
}
function parse_c_p_q() {
var result0, result1, result2;
var pos0, pos1;
pos0 = pos;
pos1 = pos;
if (input.substr(pos, 1).toLowerCase() === "q") {
result0 = input.substr(pos, 1);
pos++;
} else {
result0 = null;
if (reportFailures === 0) {
matchFailed("\"q\"");
}
}
if (result0 !== null) {
result1 = parse_EQUAL();
if (result1 !== null) {
result2 = parse_qvalue();
if (result2 !== null) {
result0 = [result0, result1, result2];
} else {
result0 = null;
pos = pos1;
}
} else {
result0 = null;
pos = pos1;
}
} else {
result0 = null;
pos = pos1;
}
if (result0 !== null) {
result0 = function (offset, q) {
if (!data.params) data.params = {};
data.params['q'] = q;
}(pos0, result0[2]);
}
if (result0 === null) {
pos = pos0;
}
return result0;
}
function parse_c_p_expires() {
var result0, result1, result2;
var pos0, pos1;
pos0 = pos;
pos1 = pos;
if (input.substr(pos, 7).toLowerCase() === "expires") {
result0 = input.substr(pos, 7);
pos += 7;
} else {
result0 = null;
if (reportFailures === 0) {
matchFailed("\"expires\"");
}
}
if (result0 !== null) {
result1 = parse_EQUAL();
if (result1 !== null) {
result2 = parse_delta_seconds();
if (result2 !== null) {
result0 = [result0, result1, result2];
} else {
result0 = null;
pos = pos1;
}
} else {
result0 = null;
pos = pos1;
}
} else {
result0 = null;
pos = pos1;
}
if (result0 !== null) {
result0 = function (offset, expires) {
if (!data.params) data.params = {};
data.params['expires'] = expires;
}(pos0, result0[2]);
}
if (result0 === null) {
pos = pos0;
}
return result0;
}
function parse_delta_seconds() {
var result0, result1;
var pos0;
pos0 = pos;
result1 = parse_DIGIT();
if (result1 !== null) {
result0 = [];
while (result1 !== null) {
result0.push(result1);
result1 = parse_DIGIT();
}
} else {
result0 = null;
}
if (result0 !== null) {
result0 = function (offset, delta_seconds) {
return parseInt(delta_seconds.join(''));
}(pos0, result0);
}
if (result0 === null) {
pos = pos0;
}
return result0;
}
function parse_qvalue() {
var result0, result1, result2, result3, result4;
var pos0, pos1, pos2;
pos0 = pos;
pos1 = pos;
if (input.charCodeAt(pos) === 48) {
result0 = "0";
pos++;
} else {
result0 = null;
if (reportFailures === 0) {
matchFailed("\"0\"");
}
}
if (result0 !== null) {
pos2 = pos;
if (input.charCodeAt(pos) === 46) {
result1 = ".";
pos++;
} else {
result1 = null;
if (reportFailures === 0) {
matchFailed("\".\"");
}
}
if (result1 !== null) {
result2 = parse_DIGIT();
result2 = result2 !== null ? result2 : "";
if (result2 !== null) {
result3 = parse_DIGIT();
result3 = result3 !== null ? result3 : "";
if (result3 !== null) {
result4 = parse_DIGIT();
result4 = result4 !== null ? result4 : "";
if (result4 !== null) {
result1 = [result1, result2, result3, result4];
} else {
result1 = null;
pos = pos2;
}
} else {
result1 = null;
pos = pos2;
}
} else {
result1 = null;
pos = pos2;
}
} else {
result1 = null;
pos = pos2;
}
result1 = result1 !== null ? result1 : "";
if (result1 !== null) {
result0 = [result0, result1];
} else {
result0 = null;
pos = pos1;
}
} else {
result0 = null;
pos = pos1;
}
if (result0 !== null) {
result0 = function (offset) {
return parseFloat(input.substring(pos, offset));
}(pos0);
}
if (result0 === null) {
pos = pos0;
}
return result0;
}
function parse_generic_param() {
var result0, result1, result2;
var pos0, pos1, pos2;
pos0 = pos;
pos1 = pos;
result0 = parse_token();
if (result0 !== null) {
pos2 = pos;
result1 = parse_EQUAL();
if (result1 !== null) {
result2 = parse_gen_value();
if (result2 !== null) {
result1 = [result1, result2];
} else {
result1 = null;
pos = pos2;
}
} else {
result1 = null;
pos = pos2;
}
result1 = result1 !== null ? result1 : "";
if (result1 !== null) {
result0 = [result0, result1];
} else {
result0 = null;
pos = pos1;
}
} else {
result0 = null;
pos = pos1;
}
if (result0 !== null) {
result0 = function (offset, param, value) {
if (!data.params) data.params = {};
if (typeof value === 'undefined') {
value = undefined;
} else {
value = value[1];
}
data.params[param.toLowerCase()] = value;
}(pos0, result0[0], result0[1]);
}
if (result0 === null) {
pos = pos0;
}
return result0;
}
function parse_gen_value() {
var result0;
result0 = parse_token();
if (result0 === null) {
result0 = parse_host();
if (result0 === null) {
result0 = parse_quoted_string();
}
}
return result0;
}
function parse_Content_Disposition() {
var result0, result1, result2, result3;
var pos0, pos1;
pos0 = pos;
result0 = parse_disp_type();
if (result0 !== null) {
result1 = [];
pos1 = pos;
result2 = parse_SEMI();
if (result2 !== null) {
result3 = parse_disp_param();
if (result3 !== null) {
result2 = [result2, result3];
} else {
result2 = null;
pos = pos1;
}
} else {
result2 = null;
pos = pos1;
}
while (result2 !== null) {
result1.push(result2);
pos1 = pos;
result2 = parse_SEMI();
if (result2 !== null) {
result3 = parse_disp_param();
if (result3 !== null) {
result2 = [result2, result3];
} else {
result2 = null;
pos = pos1;
}
} else {
result2 = null;
pos = pos1;
}
}
if (result1 !== null) {
result0 = [result0, result1];
} else {
result0 = null;
pos = pos0;
}
} else {
result0 = null;
pos = pos0;
}
return result0;
}
function parse_disp_type() {
var result0;
if (input.substr(pos, 6).toLowerCase() === "render") {
result0 = input.substr(pos, 6);
pos += 6;
} else {
result0 = null;
if (reportFailures === 0) {
matchFailed("\"render\"");
}
}
if (result0 === null) {
if (input.substr(pos, 7).toLowerCase() === "session") {
result0 = input.substr(pos, 7);
pos += 7;
} else {
result0 = null;
if (reportFailures === 0) {
matchFailed("\"session\"");
}
}
if (result0 === null) {
if (input.substr(pos, 4).toLowerCase() === "icon") {
result0 = input.substr(pos, 4);
pos += 4;
} else {
result0 = null;
if (reportFailures === 0) {
matchFailed("\"icon\"");
}
}
if (result0 === null) {
if (input.substr(pos, 5).toLowerCase() === "alert") {
result0 = input.substr(pos, 5);
pos += 5;
} else {
result0 = null;
if (reportFailures === 0) {
matchFailed("\"alert\"");
}
}
if (result0 === null) {
result0 = parse_token();
}
}
}
}
return result0;
}
function parse_disp_param() {
var result0;
result0 = parse_handling_param();
if (result0 === null) {
result0 = parse_generic_param();
}
return result0;
}
function parse_handling_param() {
var result0, result1, result2;
var pos0;
pos0 = pos;
if (input.substr(pos, 8).toLowerCase() === "handling") {
result0 = input.substr(pos, 8);
pos += 8;
} else {
result0 = null;
if (reportFailures === 0) {
matchFailed("\"handling\"");
}
}
if (result0 !== null) {
result1 = parse_EQUAL();
if (result1 !== null) {
if (input.substr(pos, 8).toLowerCase() === "optional") {
result2 = input.substr(pos, 8);
pos += 8;
} else {
result2 = null;
if (reportFailures === 0) {
matchFailed("\"optional\"");
}
}
if (result2 === null) {
if (input.substr(pos, 8).toLowerCase() === "required") {
result2 = input.substr(pos, 8);
pos += 8;
} else {
result2 = null;
if (reportFailures === 0) {
matchFailed("\"required\"");
}
}
if (result2 === null) {
result2 = parse_token();
}
}
if (result2 !== null) {
result0 = [result0, result1, result2];
} else {
result0 = null;
pos = pos0;
}
} else {
result0 = null;
pos = pos0;
}
} else {
result0 = null;
pos = pos0;
}
return result0;
}
function parse_Content_Encoding() {
var result0, result1, result2, result3;
var pos0, pos1;
pos0 = pos;
result0 = parse_token();
if (result0 !== null) {
result1 = [];
pos1 = pos;
result2 = parse_COMMA();
if (result2 !== null) {
result3 = parse_token();
if (result3 !== null) {
result2 = [result2, result3];
} else {
result2 = null;
pos = pos1;
}
} else {
result2 = null;
pos = pos1;
}
while (result2 !== null) {
result1.push(result2);
pos1 = pos;
result2 = parse_COMMA();
if (result2 !== null) {
result3 = parse_token();
if (result3 !== null) {
result2 = [result2, result3];
} else {
result2 = null;
pos = pos1;
}
} else {
result2 = null;
pos = pos1;
}
}
if (result1 !== null) {
result0 = [result0, result1];
} else {
result0 = null;
pos = pos0;
}
} else {
result0 = null;
pos = pos0;
}
return result0;
}
function parse_Content_Length() {
var result0, result1;
var pos0;
pos0 = pos;
result1 = parse_DIGIT();
if (result1 !== null) {
result0 = [];
while (result1 !== null) {
result0.push(result1);
result1 = parse_DIGIT();
}
} else {
result0 = null;
}
if (result0 !== null) {
result0 = function (offset, length) {
data = parseInt(length.join(''));
}(pos0, result0);
}
if (result0 === null) {
pos = pos0;
}
return result0;
}
function parse_Content_Type() {
var result0;
var pos0;
pos0 = pos;
result0 = parse_media_type();
if (result0 !== null) {
result0 = function (offset) {
data = input.substring(pos, offset);
}(pos0);
}
if (result0 === null) {
pos = pos0;
}
return result0;
}
function parse_media_type() {
var result0, result1, result2, result3, result4, result5;
var pos0, pos1;
pos0 = pos;
result0 = parse_m_type();
if (result0 !== null) {
result1 = parse_SLASH();
if (result1 !== null) {
result2 = parse_m_subtype();
if (result2 !== null) {
result3 = [];
pos1 = pos;
result4 = parse_SEMI();
if (result4 !== null) {
result5 = parse_m_parameter();
if (result5 !== null) {
result4 = [result4, result5];
} else {
result4 = null;
pos = pos1;
}
} else {
result4 = null;
pos = pos1;
}
while (result4 !== null) {
result3.push(result4);
pos1 = pos;
result4 = parse_SEMI();
if (result4 !== null) {
result5 = parse_m_parameter();
if (result5 !== null) {
result4 = [result4, result5];
} else {
result4 = null;
pos = pos1;
}
} else {
result4 = null;
pos = pos1;
}
}
if (result3 !== null) {
result0 = [result0, result1, result2, result3];
} else {
result0 = null;
pos = pos0;
}
} else {
result0 = null;
pos = pos0;
}
} else {
result0 = null;
pos = pos0;
}
} else {
result0 = null;
pos = pos0;
}
return result0;
}
function parse_m_type() {
var result0;
result0 = parse_discrete_type();
if (result0 === null) {
result0 = parse_composite_type();
}
return result0;
}
function parse_discrete_type() {
var result0;
if (input.substr(pos, 4).toLowerCase() === "text") {
result0 = input.substr(pos, 4);
pos += 4;
} else {
result0 = null;
if (reportFailures === 0) {
matchFailed("\"text\"");
}
}
if (result0 === null) {
if (input.substr(pos, 5).toLowerCase() === "image") {
result0 = input.substr(pos, 5);
pos += 5;
} else {
result0 = null;
if (reportFailures === 0) {
matchFailed("\"image\"");
}
}
if (result0 === null) {
if (input.substr(pos, 5).toLowerCase() === "audio") {
result0 = input.substr(pos, 5);
pos += 5;
} else {
result0 = null;
if (reportFailures === 0) {
matchFailed("\"audio\"");
}
}
if (result0 === null) {
if (input.substr(pos, 5).toLowerCase() === "video") {
result0 = input.substr(pos, 5);
pos += 5;
} else {
result0 = null;
if (reportFailures === 0) {
matchFailed("\"video\"");
}
}
if (result0 === null) {
if (input.substr(pos, 11).toLowerCase() === "application") {
result0 = input.substr(pos, 11);
pos += 11;
} else {
result0 = null;
if (reportFailures === 0) {
matchFailed("\"application\"");
}
}
if (result0 === null) {
result0 = parse_extension_token();
}
}
}
}
}
return result0;
}
function parse_composite_type() {
var result0;
if (input.substr(pos, 7).toLowerCase() === "message") {
result0 = input.substr(pos, 7);
pos += 7;
} else {
result0 = null;
if (reportFailures === 0) {
matchFailed("\"message\"");
}
}
if (result0 === null) {
if (input.substr(pos, 9).toLowerCase() === "multipart") {
result0 = input.substr(pos, 9);
pos += 9;
} else {
result0 = null;
if (reportFailures === 0) {
matchFailed("\"multipart\"");
}
}
if (result0 === null) {
result0 = parse_extension_token();
}
}
return result0;
}
function parse_extension_token() {
var result0;
result0 = parse_token();
if (result0 === null) {
result0 = parse_x_token();
}
return result0;
}
function parse_x_token() {
var result0, result1;
var pos0;
pos0 = pos;
if (input.substr(pos, 2).toLowerCase() === "x-") {
result0 = input.substr(pos, 2);
pos += 2;
} else {
result0 = null;
if (reportFailures === 0) {
matchFailed("\"x-\"");
}
}
if (result0 !== null) {
result1 = parse_token();
if (result1 !== null) {
result0 = [result0, result1];
} else {
result0 = null;
pos = pos0;
}
} else {
result0 = null;
pos = pos0;
}
return result0;
}
function parse_m_subtype() {
var result0;
result0 = parse_extension_token();
if (result0 === null) {
result0 = parse_token();
}
return result0;
}
function parse_m_parameter() {
var result0, result1, result2;
var pos0;
pos0 = pos;
result0 = parse_token();
if (result0 !== null) {
result1 = parse_EQUAL();
if (result1 !== null) {
result2 = parse_m_value();
if (result2 !== null) {
result0 = [result0, result1, result2];
} else {
result0 = null;
pos = pos0;
}
} else {
result0 = null;
pos = pos0;
}
} else {
result0 = null;
pos = pos0;
}
return result0;
}
function parse_m_value() {
var result0;
result0 = parse_token();
if (result0 === null) {
result0 = parse_quoted_string();
}
return result0;
}
function parse_CSeq() {
var result0, result1, result2;
var pos0;
pos0 = pos;
result0 = parse_CSeq_value();
if (result0 !== null) {
result1 = parse_LWS();
if (result1 !== null) {
result2 = parse_Method();
if (result2 !== null) {
result0 = [result0, result1, result2];
} else {
result0 = null;
pos = pos0;
}
} else {
result0 = null;
pos = pos0;
}
} else {
result0 = null;
pos = pos0;
}
return result0;
}
function parse_CSeq_value() {
var result0, result1;
var pos0;
pos0 = pos;
result1 = parse_DIGIT();
if (result1 !== null) {
result0 = [];
while (result1 !== null) {
result0.push(result1);
result1 = parse_DIGIT();
}
} else {
result0 = null;
}
if (result0 !== null) {
result0 = function (offset, cseq_value) {
data.value = parseInt(cseq_value.join(''));
}(pos0, result0);
}
if (result0 === null) {
pos = pos0;
}
return result0;
}
function parse_Expires() {
var result0;
var pos0;
pos0 = pos;
result0 = parse_delta_seconds();
if (result0 !== null) {
result0 = function (offset, expires) {
data = expires;
}(pos0, result0);
}
if (result0 === null) {
pos = pos0;
}
return result0;
}
function parse_Event() {
var result0, result1, result2, result3;
var pos0, pos1, pos2;
pos0 = pos;
pos1 = pos;
result0 = parse_event_type();
if (result0 !== null) {
result1 = [];
pos2 = pos;
result2 = parse_SEMI();
if (result2 !== null) {
result3 = parse_generic_param();
if (result3 !== null) {
result2 = [result2, result3];
} else {
result2 = null;
pos = pos2;
}
} else {
result2 = null;
pos = pos2;
}
while (result2 !== null) {
result1.push(result2);
pos2 = pos;
result2 = parse_SEMI();
if (result2 !== null) {
result3 = parse_generic_param();
if (result3 !== null) {
result2 = [result2, result3];
} else {
result2 = null;
pos = pos2;
}
} else {
result2 = null;
pos = pos2;
}
}
if (result1 !== null) {
result0 = [result0, result1];
} else {
result0 = null;
pos = pos1;
}
} else {
result0 = null;
pos = pos1;
}
if (result0 !== null) {
result0 = function (offset, event_type) {
data.event = event_type.join('').toLowerCase();
}(pos0, result0[0]);
}
if (result0 === null) {
pos = pos0;
}
return result0;
}
function parse_event_type() {
var result0, result1, result2, result3;
var pos0, pos1;
pos0 = pos;
result0 = parse_token_nodot();
if (result0 !== null) {
result1 = [];
pos1 = pos;
if (input.charCodeAt(pos) === 46) {
result2 = ".";
pos++;
} else {
result2 = null;
if (reportFailures === 0) {
matchFailed("\".\"");
}
}
if (result2 !== null) {
result3 = parse_token_nodot();
if (result3 !== null) {
result2 = [result2, result3];
} else {
result2 = null;
pos = pos1;
}
} else {
result2 = null;
pos = pos1;
}
while (result2 !== null) {
result1.push(result2);
pos1 = pos;
if (input.charCodeAt(pos) === 46) {
result2 = ".";
pos++;
} else {
result2 = null;
if (reportFailures === 0) {
matchFailed("\".\"");
}
}
if (result2 !== null) {
result3 = parse_token_nodot();
if (result3 !== null) {
result2 = [result2, result3];
} else {
result2 = null;
pos = pos1;
}
} else {
result2 = null;
pos = pos1;
}
}
if (result1 !== null) {
result0 = [result0, result1];
} else {
result0 = null;
pos = pos0;
}
} else {
result0 = null;
pos = pos0;
}
return result0;
}
function parse_From() {
var result0, result1, result2, result3;
var pos0, pos1, pos2;
pos0 = pos;
pos1 = pos;
result0 = parse_SIP_URI_noparams();
if (result0 === null) {
result0 = parse_name_addr();
}
if (result0 !== null) {
result1 = [];
pos2 = pos;
result2 = parse_SEMI();
if (result2 !== null) {
result3 = parse_from_param();
if (result3 !== null) {
result2 = [result2, result3];
} else {
result2 = null;
pos = pos2;
}
} else {
result2 = null;
pos = pos2;
}
while (result2 !== null) {
result1.push(result2);
pos2 = pos;
result2 = parse_SEMI();
if (result2 !== null) {
result3 = parse_from_param();
if (result3 !== null) {
result2 = [result2, result3];
} else {
result2 = null;
pos = pos2;
}
} else {
result2 = null;
pos = pos2;
}
}
if (result1 !== null) {
result0 = [result0, result1];
} else {
result0 = null;
pos = pos1;
}
} else {
result0 = null;
pos = pos1;
}
if (result0 !== null) {
result0 = function (offset) {
var tag = data.tag;
try {
data = new NameAddrHeader(data.uri, data.display_name, data.params);
if (tag) {
data.setParam('tag', tag);
}
} catch (e) {
data = -1;
}
}(pos0);
}
if (result0 === null) {
pos = pos0;
}
return result0;
}
function parse_from_param() {
var result0;
result0 = parse_tag_param();
if (result0 === null) {
result0 = parse_generic_param();
}
return result0;
}
function parse_tag_param() {
var result0, result1, result2;
var pos0, pos1;
pos0 = pos;
pos1 = pos;
if (input.substr(pos, 3).toLowerCase() === "tag") {
result0 = input.substr(pos, 3);
pos += 3;
} else {
result0 = null;
if (reportFailures === 0) {
matchFailed("\"tag\"");
}
}
if (result0 !== null) {
result1 = parse_EQUAL();
if (result1 !== null) {
result2 = parse_token();
if (result2 !== null) {
result0 = [result0, result1, result2];
} else {
result0 = null;
pos = pos1;
}
} else {
result0 = null;
pos = pos1;
}
} else {
result0 = null;
pos = pos1;
}
if (result0 !== null) {
result0 = function (offset, tag) {
data.tag = tag;
}(pos0, result0[2]);
}
if (result0 === null) {
pos = pos0;
}
return result0;
}
function parse_Max_Forwards() {
var result0, result1;
var pos0;
pos0 = pos;
result1 = parse_DIGIT();
if (result1 !== null) {
result0 = [];
while (result1 !== null) {
result0.push(result1);
result1 = parse_DIGIT();
}
} else {
result0 = null;
}
if (result0 !== null) {
result0 = function (offset, forwards) {
data = parseInt(forwards.join(''));
}(pos0, result0);
}
if (result0 === null) {
pos = pos0;
}
return result0;
}
function parse_Min_Expires() {
var result0;
var pos0;
pos0 = pos;
result0 = parse_delta_seconds();
if (result0 !== null) {
result0 = function (offset, min_expires) {
data = min_expires;
}(pos0, result0);
}
if (result0 === null) {
pos = pos0;
}
return result0;
}
function parse_Name_Addr_Header() {
var result0, result1, result2, result3, result4, result5, result6;
var pos0, pos1, pos2;
pos0 = pos;
pos1 = pos;
result0 = [];
result1 = parse_display_name();
while (result1 !== null) {
result0.push(result1);
result1 = parse_display_name();
}
if (result0 !== null) {
result1 = parse_LAQUOT();
if (result1 !== null) {
result2 = parse_SIP_URI();
if (result2 !== null) {
result3 = parse_RAQUOT();
if (result3 !== null) {
result4 = [];
pos2 = pos;
result5 = parse_SEMI();
if (result5 !== null) {
result6 = parse_generic_param();
if (result6 !== null) {
result5 = [result5, result6];
} else {
result5 = null;
pos = pos2;
}
} else {
result5 = null;
pos = pos2;
}
while (result5 !== null) {
result4.push(result5);
pos2 = pos;
result5 = parse_SEMI();
if (result5 !== null) {
result6 = parse_generic_param();
if (result6 !== null) {
result5 = [result5, result6];
} else {
result5 = null;
pos = pos2;
}
} else {
result5 = null;
pos = pos2;
}
}
if (result4 !== null) {
result0 = [result0, result1, result2, result3, result4];
} else {
result0 = null;
pos = pos1;
}
} else {
result0 = null;
pos = pos1;
}
} else {
result0 = null;
pos = pos1;
}
} else {
result0 = null;
pos = pos1;
}
} else {
result0 = null;
pos = pos1;
}
if (result0 !== null) {
result0 = function (offset) {
try {
data = new NameAddrHeader(data.uri, data.display_name, data.params);
} catch (e) {
data = -1;
}
}(pos0);
}
if (result0 === null) {
pos = pos0;
}
return result0;
}
function parse_Proxy_Authenticate() {
var result0;
result0 = parse_challenge();
return result0;
}
function parse_challenge() {
var result0, result1, result2, result3, result4, result5;
var pos0, pos1;
pos0 = pos;
if (input.substr(pos, 6).toLowerCase() === "digest") {
result0 = input.substr(pos, 6);
pos += 6;
} else {
result0 = null;
if (reportFailures === 0) {
matchFailed("\"Digest\"");
}
}
if (result0 !== null) {
result1 = parse_LWS();
if (result1 !== null) {
result2 = parse_digest_cln();
if (result2 !== null) {
result3 = [];
pos1 = pos;
result4 = parse_COMMA();
if (result4 !== null) {
result5 = parse_digest_cln();
if (result5 !== null) {
result4 = [result4, result5];
} else {
result4 = null;
pos = pos1;
}
} else {
result4 = null;
pos = pos1;
}
while (result4 !== null) {
result3.push(result4);
pos1 = pos;
result4 = parse_COMMA();
if (result4 !== null) {
result5 = parse_digest_cln();
if (result5 !== null) {
result4 = [result4, result5];
} else {
result4 = null;
pos = pos1;
}
} else {
result4 = null;
pos = pos1;
}
}
if (result3 !== null) {
result0 = [result0, result1, result2, result3];
} else {
result0 = null;
pos = pos0;
}
} else {
result0 = null;
pos = pos0;
}
} else {
result0 = null;
pos = pos0;
}
} else {
result0 = null;
pos = pos0;
}
if (result0 === null) {
result0 = parse_other_challenge();
}
return result0;
}
function parse_other_challenge() {
var result0, result1, result2, result3, result4, result5;
var pos0, pos1;
pos0 = pos;
result0 = parse_token();
if (result0 !== null) {
result1 = parse_LWS();
if (result1 !== null) {
result2 = parse_auth_param();
if (result2 !== null) {
result3 = [];
pos1 = pos;
result4 = parse_COMMA();
if (result4 !== null) {
result5 = parse_auth_param();
if (result5 !== null) {
result4 = [result4, result5];
} else {
result4 = null;
pos = pos1;
}
} else {
result4 = null;
pos = pos1;
}
while (result4 !== null) {
result3.push(result4);
pos1 = pos;
result4 = parse_COMMA();
if (result4 !== null) {
result5 = parse_auth_param();
if (result5 !== null) {
result4 = [result4, result5];
} else {
result4 = null;
pos = pos1;
}
} else {
result4 = null;
pos = pos1;
}
}
if (result3 !== null) {
result0 = [result0, result1, result2, result3];
} else {
result0 = null;
pos = pos0;
}
} else {
result0 = null;
pos = pos0;
}
} else {
result0 = null;
pos = pos0;
}
} else {
result0 = null;
pos = pos0;
}
return result0;
}
function parse_auth_param() {
var result0, result1, result2;
var pos0;
pos0 = pos;
result0 = parse_token();
if (result0 !== null) {
result1 = parse_EQUAL();
if (result1 !== null) {
result2 = parse_token();
if (result2 === null) {
result2 = parse_quoted_string();
}
if (result2 !== null) {
result0 = [result0, result1, result2];
} else {
result0 = null;
pos = pos0;
}
} else {
result0 = null;
pos = pos0;
}
} else {
result0 = null;
pos = pos0;
}
return result0;
}
function parse_digest_cln() {
var result0;
result0 = parse_realm();
if (result0 === null) {
result0 = parse_domain();
if (result0 === null) {
result0 = parse_nonce();
if (result0 === null) {
result0 = parse_opaque();
if (result0 === null) {
result0 = parse_stale();
if (result0 === null) {
result0 = parse_algorithm();
if (result0 === null) {
result0 = parse_qop_options();
if (result0 === null) {
result0 = parse_auth_param();
}
}
}
}
}
}
}
return result0;
}
function parse_realm() {
var result0, result1, result2;
var pos0;
pos0 = pos;
if (input.substr(pos, 5).toLowerCase() === "realm") {
result0 = input.substr(pos, 5);
pos += 5;
} else {
result0 = null;
if (reportFailures === 0) {
matchFailed("\"realm\"");
}
}
if (result0 !== null) {
result1 = parse_EQUAL();
if (result1 !== null) {
result2 = parse_realm_value();
if (result2 !== null) {
result0 = [result0, result1, result2];
} else {
result0 = null;
pos = pos0;
}
} else {
result0 = null;
pos = pos0;
}
} else {
result0 = null;
pos = pos0;
}
return result0;
}
function parse_realm_value() {
var result0;
var pos0;
pos0 = pos;
result0 = parse_quoted_string_clean();
if (result0 !== null) {
result0 = function (offset, realm) {
data.realm = realm;
}(pos0, result0);
}
if (result0 === null) {
pos = pos0;
}
return result0;
}
function parse_domain() {
var result0, result1, result2, result3, result4, result5, result6;
var pos0, pos1;
pos0 = pos;
if (input.substr(pos, 6).toLowerCase() === "domain") {
result0 = input.substr(pos, 6);
pos += 6;
} else {
result0 = null;
if (reportFailures === 0) {
matchFailed("\"domain\"");
}
}
if (result0 !== null) {
result1 = parse_EQUAL();
if (result1 !== null) {
result2 = parse_LDQUOT();
if (result2 !== null) {
result3 = parse_URI();
if (result3 !== null) {
result4 = [];
pos1 = pos;
result6 = parse_SP();
if (result6 !== null) {
result5 = [];
while (result6 !== null) {
result5.push(result6);
result6 = parse_SP();
}
} else {
result5 = null;
}
if (result5 !== null) {
result6 = parse_URI();
if (result6 !== null) {
result5 = [result5, result6];
} else {
result5 = null;
pos = pos1;
}
} else {
result5 = null;
pos = pos1;
}
while (result5 !== null) {
result4.push(result5);
pos1 = pos;
result6 = parse_SP();
if (result6 !== null) {
result5 = [];
while (result6 !== null) {
result5.push(result6);
result6 = parse_SP();
}
} else {
result5 = null;
}
if (result5 !== null) {
result6 = parse_URI();
if (result6 !== null) {
result5 = [result5, result6];
} else {
result5 = null;
pos = pos1;
}
} else {
result5 = null;
pos = pos1;
}
}
if (result4 !== null) {
result5 = parse_RDQUOT();
if (result5 !== null) {
result0 = [result0, result1, result2, result3, result4, result5];
} else {
result0 = null;
pos = pos0;
}
} else {
result0 = null;
pos = pos0;
}
} else {
result0 = null;
pos = pos0;
}
} else {
result0 = null;
pos = pos0;
}
} else {
result0 = null;
pos = pos0;
}
} else {
result0 = null;
pos = pos0;
}
return result0;
}
function parse_URI() {
var result0;
result0 = parse_absoluteURI();
if (result0 === null) {
result0 = parse_abs_path();
}
return result0;
}
function parse_nonce() {
var result0, result1, result2;
var pos0;
pos0 = pos;
if (input.substr(pos, 5).toLowerCase() === "nonce") {
result0 = input.substr(pos, 5);
pos += 5;
} else {
result0 = null;
if (reportFailures === 0) {
matchFailed("\"nonce\"");
}
}
if (result0 !== null) {
result1 = parse_EQUAL();
if (result1 !== null) {
result2 = parse_nonce_value();
if (result2 !== null) {
result0 = [result0, result1, result2];
} else {
result0 = null;
pos = pos0;
}
} else {
result0 = null;
pos = pos0;
}
} else {
result0 = null;
pos = pos0;
}
return result0;
}
function parse_nonce_value() {
var result0;
var pos0;
pos0 = pos;
result0 = parse_quoted_string_clean();
if (result0 !== null) {
result0 = function (offset, nonce) {
data.nonce = nonce;
}(pos0, result0);
}
if (result0 === null) {
pos = pos0;
}
return result0;
}
function parse_opaque() {
var result0, result1, result2;
var pos0, pos1;
pos0 = pos;
pos1 = pos;
if (input.substr(pos, 6).toLowerCase() === "opaque") {
result0 = input.substr(pos, 6);
pos += 6;
} else {
result0 = null;
if (reportFailures === 0) {
matchFailed("\"opaque\"");
}
}
if (result0 !== null) {
result1 = parse_EQUAL();
if (result1 !== null) {
result2 = parse_quoted_string_clean();
if (result2 !== null) {
result0 = [result0, result1, result2];
} else {
result0 = null;
pos = pos1;
}
} else {
result0 = null;
pos = pos1;
}
} else {
result0 = null;
pos = pos1;
}
if (result0 !== null) {
result0 = function (offset, opaque) {
data.opaque = opaque;
}(pos0, result0[2]);
}
if (result0 === null) {
pos = pos0;
}
return result0;
}
function parse_stale() {
var result0, result1, result2;
var pos0, pos1;
pos0 = pos;
if (input.substr(pos, 5).toLowerCase() === "stale") {
result0 = input.substr(pos, 5);
pos += 5;
} else {
result0 = null;
if (reportFailures === 0) {
matchFailed("\"stale\"");
}
}
if (result0 !== null) {
result1 = parse_EQUAL();
if (result1 !== null) {
pos1 = pos;
if (input.substr(pos, 4).toLowerCase() === "true") {
result2 = input.substr(pos, 4);
pos += 4;
} else {
result2 = null;
if (reportFailures === 0) {
matchFailed("\"true\"");
}
}
if (result2 !== null) {
result2 = function (offset) {
data.stale = true;
}(pos1);
}
if (result2 === null) {
pos = pos1;
}
if (result2 === null) {
pos1 = pos;
if (input.substr(pos, 5).toLowerCase() === "false") {
result2 = input.substr(pos, 5);
pos += 5;
} else {
result2 = null;
if (reportFailures === 0) {
matchFailed("\"false\"");
}
}
if (result2 !== null) {
result2 = function (offset) {
data.stale = false;
}(pos1);
}
if (result2 === null) {
pos = pos1;
}
}
if (result2 !== null) {
result0 = [result0, result1, result2];
} else {
result0 = null;
pos = pos0;
}
} else {
result0 = null;
pos = pos0;
}
} else {
result0 = null;
pos = pos0;
}
return result0;
}
function parse_algorithm() {
var result0, result1, result2;
var pos0, pos1;
pos0 = pos;
pos1 = pos;
if (input.substr(pos, 9).toLowerCase() === "algorithm") {
result0 = input.substr(pos, 9);
pos += 9;
} else {
result0 = null;
if (reportFailures === 0) {
matchFailed("\"algorithm\"");
}
}
if (result0 !== null) {
result1 = parse_EQUAL();
if (result1 !== null) {
if (input.substr(pos, 3).toLowerCase() === "md5") {
result2 = input.substr(pos, 3);
pos += 3;
} else {
result2 = null;
if (reportFailures === 0) {
matchFailed("\"MD5\"");
}
}
if (result2 === null) {
if (input.substr(pos, 8).toLowerCase() === "md5-sess") {
result2 = input.substr(pos, 8);
pos += 8;
} else {
result2 = null;
if (reportFailures === 0) {
matchFailed("\"MD5-sess\"");
}
}
if (result2 === null) {
result2 = parse_token();
}
}
if (result2 !== null) {
result0 = [result0, result1, result2];
} else {
result0 = null;
pos = pos1;
}
} else {
result0 = null;
pos = pos1;
}
} else {
result0 = null;
pos = pos1;
}
if (result0 !== null) {
result0 = function (offset, algorithm) {
data.algorithm = algorithm.toUpperCase();
}(pos0, result0[2]);
}
if (result0 === null) {
pos = pos0;
}
return result0;
}
function parse_qop_options() {
var result0, result1, result2, result3, result4, result5, result6;
var pos0, pos1, pos2;
pos0 = pos;
if (input.substr(pos, 3).toLowerCase() === "qop") {
result0 = input.substr(pos, 3);
pos += 3;
} else {
result0 = null;
if (reportFailures === 0) {
matchFailed("\"qop\"");
}
}
if (result0 !== null) {
result1 = parse_EQUAL();
if (result1 !== null) {
result2 = parse_LDQUOT();
if (result2 !== null) {
pos1 = pos;
result3 = parse_qop_value();
if (result3 !== null) {
result4 = [];
pos2 = pos;
if (input.charCodeAt(pos) === 44) {
result5 = ",";
pos++;
} else {
result5 = null;
if (reportFailures === 0) {
matchFailed("\",\"");
}
}
if (result5 !== null) {
result6 = parse_qop_value();
if (result6 !== null) {
result5 = [result5, result6];
} else {
result5 = null;
pos = pos2;
}
} else {
result5 = null;
pos = pos2;
}
while (result5 !== null) {
result4.push(result5);
pos2 = pos;
if (input.charCodeAt(pos) === 44) {
result5 = ",";
pos++;
} else {
result5 = null;
if (reportFailures === 0) {
matchFailed("\",\"");
}
}
if (result5 !== null) {
result6 = parse_qop_value();
if (result6 !== null) {
result5 = [result5, result6];
} else {
result5 = null;
pos = pos2;
}
} else {
result5 = null;
pos = pos2;
}
}
if (result4 !== null) {
result3 = [result3, result4];
} else {
result3 = null;
pos = pos1;
}
} else {
result3 = null;
pos = pos1;
}
if (result3 !== null) {
result4 = parse_RDQUOT();
if (result4 !== null) {
result0 = [result0, result1, result2, result3, result4];
} else {
result0 = null;
pos = pos0;
}
} else {
result0 = null;
pos = pos0;
}
} else {
result0 = null;
pos = pos0;
}
} else {
result0 = null;
pos = pos0;
}
} else {
result0 = null;
pos = pos0;
}
return result0;
}
function parse_qop_value() {
var result0;
var pos0;
pos0 = pos;
if (input.substr(pos, 8).toLowerCase() === "auth-int") {
result0 = input.substr(pos, 8);
pos += 8;
} else {
result0 = null;
if (reportFailures === 0) {
matchFailed("\"auth-int\"");
}
}
if (result0 === null) {
if (input.substr(pos, 4).toLowerCase() === "auth") {
result0 = input.substr(pos, 4);
pos += 4;
} else {
result0 = null;
if (reportFailures === 0) {
matchFailed("\"auth\"");
}
}
if (result0 === null) {
result0 = parse_token();
}
}
if (result0 !== null) {
result0 = function (offset, qop_value) {
data.qop || (data.qop = []);
data.qop.push(qop_value.toLowerCase());
}(pos0, result0);
}
if (result0 === null) {
pos = pos0;
}
return result0;
}
function parse_Proxy_Require() {
var result0, result1, result2, result3;
var pos0, pos1;
pos0 = pos;
result0 = parse_token();
if (result0 !== null) {
result1 = [];
pos1 = pos;
result2 = parse_COMMA();
if (result2 !== null) {
result3 = parse_token();
if (result3 !== null) {
result2 = [result2, result3];
} else {
result2 = null;
pos = pos1;
}
} else {
result2 = null;
pos = pos1;
}
while (result2 !== null) {
result1.push(result2);
pos1 = pos;
result2 = parse_COMMA();
if (result2 !== null) {
result3 = parse_token();
if (result3 !== null) {
result2 = [result2, result3];
} else {
result2 = null;
pos = pos1;
}
} else {
result2 = null;
pos = pos1;
}
}
if (result1 !== null) {
result0 = [result0, result1];
} else {
result0 = null;
pos = pos0;
}
} else {
result0 = null;
pos = pos0;
}
return result0;
}
function parse_Record_Route() {
var result0, result1, result2, result3;
var pos0, pos1, pos2;
pos0 = pos;
pos1 = pos;
result0 = parse_rec_route();
if (result0 !== null) {
result1 = [];
pos2 = pos;
result2 = parse_COMMA();
if (result2 !== null) {
result3 = parse_rec_route();
if (result3 !== null) {
result2 = [result2, result3];
} else {
result2 = null;
pos = pos2;
}
} else {
result2 = null;
pos = pos2;
}
while (result2 !== null) {
result1.push(result2);
pos2 = pos;
result2 = parse_COMMA();
if (result2 !== null) {
result3 = parse_rec_route();
if (result3 !== null) {
result2 = [result2, result3];
} else {
result2 = null;
pos = pos2;
}
} else {
result2 = null;
pos = pos2;
}
}
if (result1 !== null) {
result0 = [result0, result1];
} else {
result0 = null;
pos = pos1;
}
} else {
result0 = null;
pos = pos1;
}
if (result0 !== null) {
result0 = function (offset) {
var idx, length;
length = data.multi_header.length;
for (idx = 0; idx < length; idx++) {
if (data.multi_header[idx].parsed === null) {
data = null;
break;
}
}
if (data !== null) {
data = data.multi_header;
} else {
data = -1;
}
}(pos0);
}
if (result0 === null) {
pos = pos0;
}
return result0;
}
function parse_rec_route() {
var result0, result1, result2, result3;
var pos0, pos1, pos2;
pos0 = pos;
pos1 = pos;
result0 = parse_name_addr();
if (result0 !== null) {
result1 = [];
pos2 = pos;
result2 = parse_SEMI();
if (result2 !== null) {
result3 = parse_generic_param();
if (result3 !== null) {
result2 = [result2, result3];
} else {
result2 = null;
pos = pos2;
}
} else {
result2 = null;
pos = pos2;
}
while (result2 !== null) {
result1.push(result2);
pos2 = pos;
result2 = parse_SEMI();
if (result2 !== null) {
result3 = parse_generic_param();
if (result3 !== null) {
result2 = [result2, result3];
} else {
result2 = null;
pos = pos2;
}
} else {
result2 = null;
pos = pos2;
}
}
if (result1 !== null) {
result0 = [result0, result1];
} else {
result0 = null;
pos = pos1;
}
} else {
result0 = null;
pos = pos1;
}
if (result0 !== null) {
result0 = function (offset) {
var header;
if (!data.multi_header) data.multi_header = [];
try {
header = new NameAddrHeader(data.uri, data.display_name, data.params);
delete data.uri;
delete data.display_name;
delete data.params;
} catch (e) {
header = null;
}
data.multi_header.push({
'possition': pos,
'offset': offset,
'parsed': header
});
}(pos0);
}
if (result0 === null) {
pos = pos0;
}
return result0;
}
function parse_Reason() {
var result0, result1, result2, result3;
var pos0, pos1, pos2;
pos0 = pos;
pos1 = pos;
if (input.substr(pos, 3).toLowerCase() === "sip") {
result0 = input.substr(pos, 3);
pos += 3;
} else {
result0 = null;
if (reportFailures === 0) {
matchFailed("\"SIP\"");
}
}
if (result0 === null) {
result0 = parse_token();
}
if (result0 !== null) {
result1 = [];
pos2 = pos;
result2 = parse_SEMI();
if (result2 !== null) {
result3 = parse_reason_param();
if (result3 !== null) {
result2 = [result2, result3];
} else {
result2 = null;
pos = pos2;
}
} else {
result2 = null;
pos = pos2;
}
while (result2 !== null) {
result1.push(result2);
pos2 = pos;
result2 = parse_SEMI();
if (result2 !== null) {
result3 = parse_reason_param();
if (result3 !== null) {
result2 = [result2, result3];
} else {
result2 = null;
pos = pos2;
}
} else {
result2 = null;
pos = pos2;
}
}
if (result1 !== null) {
result0 = [result0, result1];
} else {
result0 = null;
pos = pos1;
}
} else {
result0 = null;
pos = pos1;
}
if (result0 !== null) {
result0 = function (offset, protocol) {
data.protocol = protocol.toLowerCase();
if (!data.params) data.params = {};
if (data.params.text && data.params.text[0] === '"') {
var text = data.params.text;
data.text = text.substring(1, text.length - 1);
delete data.params.text;
}
}(pos0, result0[0]);
}
if (result0 === null) {
pos = pos0;
}
return result0;
}
function parse_reason_param() {
var result0;
result0 = parse_reason_cause();
if (result0 === null) {
result0 = parse_generic_param();
}
return result0;
}
function parse_reason_cause() {
var result0, result1, result2, result3;
var pos0, pos1;
pos0 = pos;
pos1 = pos;
if (input.substr(pos, 5).toLowerCase() === "cause") {
result0 = input.substr(pos, 5);
pos += 5;
} else {
result0 = null;
if (reportFailures === 0) {
matchFailed("\"cause\"");
}
}
if (result0 !== null) {
result1 = parse_EQUAL();
if (result1 !== null) {
result3 = parse_DIGIT();
if (result3 !== null) {
result2 = [];
while (result3 !== null) {
result2.push(result3);
result3 = parse_DIGIT();
}
} else {
result2 = null;
}
if (result2 !== null) {
result0 = [result0, result1, result2];
} else {
result0 = null;
pos = pos1;
}
} else {
result0 = null;
pos = pos1;
}
} else {
result0 = null;
pos = pos1;
}
if (result0 !== null) {
result0 = function (offset, cause) {
data.cause = parseInt(cause.join(''));
}(pos0, result0[2]);
}
if (result0 === null) {
pos = pos0;
}
return result0;
}
function parse_Require() {
var result0, result1, result2, result3;
var pos0, pos1;
pos0 = pos;
result0 = parse_token();
if (result0 !== null) {
result1 = [];
pos1 = pos;
result2 = parse_COMMA();
if (result2 !== null) {
result3 = parse_token();
if (result3 !== null) {
result2 = [result2, result3];
} else {
result2 = null;
pos = pos1;
}
} else {
result2 = null;
pos = pos1;
}
while (result2 !== null) {
result1.push(result2);
pos1 = pos;
result2 = parse_COMMA();
if (result2 !== null) {
result3 = parse_token();
if (result3 !== null) {
result2 = [result2, result3];
} else {
result2 = null;
pos = pos1;
}
} else {
result2 = null;
pos = pos1;
}
}
if (result1 !== null) {
result0 = [result0, result1];
} else {
result0 = null;
pos = pos0;
}
} else {
result0 = null;
pos = pos0;
}
return result0;
}
function parse_Route() {
var result0, result1, result2, result3;
var pos0, pos1;
pos0 = pos;
result0 = parse_route_param();
if (result0 !== null) {
result1 = [];
pos1 = pos;
result2 = parse_COMMA();
if (result2 !== null) {
result3 = parse_route_param();
if (result3 !== null) {
result2 = [result2, result3];
} else {
result2 = null;
pos = pos1;
}
} else {
result2 = null;
pos = pos1;
}
while (result2 !== null) {
result1.push(result2);
pos1 = pos;
result2 = parse_COMMA();
if (result2 !== null) {
result3 = parse_route_param();
if (result3 !== null) {
result2 = [result2, result3];
} else {
result2 = null;
pos = pos1;
}
} else {
result2 = null;
pos = pos1;
}
}
if (result1 !== null) {
result0 = [result0, result1];
} else {
result0 = null;
pos = pos0;
}
} else {
result0 = null;
pos = pos0;
}
return result0;
}
function parse_route_param() {
var result0, result1, result2, result3;
var pos0, pos1;
pos0 = pos;
result0 = parse_name_addr();
if (result0 !== null) {
result1 = [];
pos1 = pos;
result2 = parse_SEMI();
if (result2 !== null) {
result3 = parse_generic_param();
if (result3 !== null) {
result2 = [result2, result3];
} else {
result2 = null;
pos = pos1;
}
} else {
result2 = null;
pos = pos1;
}
while (result2 !== null) {
result1.push(result2);
pos1 = pos;
result2 = parse_SEMI();
if (result2 !== null) {
result3 = parse_generic_param();
if (result3 !== null) {
result2 = [result2, result3];
} else {
result2 = null;
pos = pos1;
}
} else {
result2 = null;
pos = pos1;
}
}
if (result1 !== null) {
result0 = [result0, result1];
} else {
result0 = null;
pos = pos0;
}
} else {
result0 = null;
pos = pos0;
}
return result0;
}
function parse_Subscription_State() {
var result0, result1, result2, result3;
var pos0, pos1;
pos0 = pos;
result0 = parse_substate_value();
if (result0 !== null) {
result1 = [];
pos1 = pos;
result2 = parse_SEMI();
if (result2 !== null) {
result3 = parse_subexp_params();
if (result3 !== null) {
result2 = [result2, result3];
} else {
result2 = null;
pos = pos1;
}
} else {
result2 = null;
pos = pos1;
}
while (result2 !== null) {
result1.push(result2);
pos1 = pos;
result2 = parse_SEMI();
if (result2 !== null) {
result3 = parse_subexp_params();
if (result3 !== null) {
result2 = [result2, result3];
} else {
result2 = null;
pos = pos1;
}
} else {
result2 = null;
pos = pos1;
}
}
if (result1 !== null) {
result0 = [result0, result1];
} else {
result0 = null;
pos = pos0;
}
} else {
result0 = null;
pos = pos0;
}
return result0;
}
function parse_substate_value() {
var result0;
var pos0;
pos0 = pos;
if (input.substr(pos, 6).toLowerCase() === "active") {
result0 = input.substr(pos, 6);
pos += 6;
} else {
result0 = null;
if (reportFailures === 0) {
matchFailed("\"active\"");
}
}
if (result0 === null) {
if (input.substr(pos, 7).toLowerCase() === "pending") {
result0 = input.substr(pos, 7);
pos += 7;
} else {
result0 = null;
if (reportFailures === 0) {
matchFailed("\"pending\"");
}
}
if (result0 === null) {
if (input.substr(pos, 10).toLowerCase() === "terminated") {
result0 = input.substr(pos, 10);
pos += 10;
} else {
result0 = null;
if (reportFailures === 0) {
matchFailed("\"terminated\"");
}
}
if (result0 === null) {
result0 = parse_token();
}
}
}
if (result0 !== null) {
result0 = function (offset) {
data.state = input.substring(pos, offset);
}(pos0);
}
if (result0 === null) {
pos = pos0;
}
return result0;
}
function parse_subexp_params() {
var result0, result1, result2;
var pos0, pos1;
pos0 = pos;
pos1 = pos;
if (input.substr(pos, 6).toLowerCase() === "reason") {
result0 = input.substr(pos, 6);
pos += 6;
} else {
result0 = null;
if (reportFailures === 0) {
matchFailed("\"reason\"");
}
}
if (result0 !== null) {
result1 = parse_EQUAL();
if (result1 !== null) {
result2 = parse_event_reason_value();
if (result2 !== null) {
result0 = [result0, result1, result2];
} else {
result0 = null;
pos = pos1;
}
} else {
result0 = null;
pos = pos1;
}
} else {
result0 = null;
pos = pos1;
}
if (result0 !== null) {
result0 = function (offset, reason) {
if (typeof reason !== 'undefined') data.reason = reason;
}(pos0, result0[2]);
}
if (result0 === null) {
pos = pos0;
}
if (result0 === null) {
pos0 = pos;
pos1 = pos;
if (input.substr(pos, 7).toLowerCase() === "expires") {
result0 = input.substr(pos, 7);
pos += 7;
} else {
result0 = null;
if (reportFailures === 0) {
matchFailed("\"expires\"");
}
}
if (result0 !== null) {
result1 = parse_EQUAL();
if (result1 !== null) {
result2 = parse_delta_seconds();
if (result2 !== null) {
result0 = [result0, result1, result2];
} else {
result0 = null;
pos = pos1;
}
} else {
result0 = null;
pos = pos1;
}
} else {
result0 = null;
pos = pos1;
}
if (result0 !== null) {
result0 = function (offset, expires) {
if (typeof expires !== 'undefined') data.expires = expires;
}(pos0, result0[2]);
}
if (result0 === null) {
pos = pos0;
}
if (result0 === null) {
pos0 = pos;
pos1 = pos;
if (input.substr(pos, 11).toLowerCase() === "retry_after") {
result0 = input.substr(pos, 11);
pos += 11;
} else {
result0 = null;
if (reportFailures === 0) {
matchFailed("\"retry_after\"");
}
}
if (result0 !== null) {
result1 = parse_EQUAL();
if (result1 !== null) {
result2 = parse_delta_seconds();
if (result2 !== null) {
result0 = [result0, result1, result2];
} else {
result0 = null;
pos = pos1;
}
} else {
result0 = null;
pos = pos1;
}
} else {
result0 = null;
pos = pos1;
}
if (result0 !== null) {
result0 = function (offset, retry_after) {
if (typeof retry_after !== 'undefined') data.retry_after = retry_after;
}(pos0, result0[2]);
}
if (result0 === null) {
pos = pos0;
}
if (result0 === null) {
result0 = parse_generic_param();
}
}
}
return result0;
}
function parse_event_reason_value() {
var result0;
if (input.substr(pos, 11).toLowerCase() === "deactivated") {
result0 = input.substr(pos, 11);
pos += 11;
} else {
result0 = null;
if (reportFailures === 0) {
matchFailed("\"deactivated\"");
}
}
if (result0 === null) {
if (input.substr(pos, 9).toLowerCase() === "probation") {
result0 = input.substr(pos, 9);
pos += 9;
} else {
result0 = null;
if (reportFailures === 0) {
matchFailed("\"probation\"");
}
}
if (result0 === null) {
if (input.substr(pos, 8).toLowerCase() === "rejected") {
result0 = input.substr(pos, 8);
pos += 8;
} else {
result0 = null;
if (reportFailures === 0) {
matchFailed("\"rejected\"");
}
}
if (result0 === null) {
if (input.substr(pos, 7).toLowerCase() === "timeout") {
result0 = input.substr(pos, 7);
pos += 7;
} else {
result0 = null;
if (reportFailures === 0) {
matchFailed("\"timeout\"");
}
}
if (result0 === null) {
if (input.substr(pos, 6).toLowerCase() === "giveup") {
result0 = input.substr(pos, 6);
pos += 6;
} else {
result0 = null;
if (reportFailures === 0) {
matchFailed("\"giveup\"");
}
}
if (result0 === null) {
if (input.substr(pos, 10).toLowerCase() === "noresource") {
result0 = input.substr(pos, 10);
pos += 10;
} else {
result0 = null;
if (reportFailures === 0) {
matchFailed("\"noresource\"");
}
}
if (result0 === null) {
if (input.substr(pos, 9).toLowerCase() === "invariant") {
result0 = input.substr(pos, 9);
pos += 9;
} else {
result0 = null;
if (reportFailures === 0) {
matchFailed("\"invariant\"");
}
}
if (result0 === null) {
result0 = parse_token();
}
}
}
}
}
}
}
return result0;
}
function parse_Subject() {
var result0;
result0 = parse_TEXT_UTF8_TRIM();
result0 = result0 !== null ? result0 : "";
return result0;
}
function parse_Supported() {
var result0, result1, result2, result3;
var pos0, pos1;
pos0 = pos;
result0 = parse_token();
if (result0 !== null) {
result1 = [];
pos1 = pos;
result2 = parse_COMMA();
if (result2 !== null) {
result3 = parse_token();
if (result3 !== null) {
result2 = [result2, result3];
} else {
result2 = null;
pos = pos1;
}
} else {
result2 = null;
pos = pos1;
}
while (result2 !== null) {
result1.push(result2);
pos1 = pos;
result2 = parse_COMMA();
if (result2 !== null) {
result3 = parse_token();
if (result3 !== null) {
result2 = [result2, result3];
} else {
result2 = null;
pos = pos1;
}
} else {
result2 = null;
pos = pos1;
}
}
if (result1 !== null) {
result0 = [result0, result1];
} else {
result0 = null;
pos = pos0;
}
} else {
result0 = null;
pos = pos0;
}
result0 = result0 !== null ? result0 : "";
return result0;
}
function parse_To() {
var result0, result1, result2, result3;
var pos0, pos1, pos2;
pos0 = pos;
pos1 = pos;
result0 = parse_SIP_URI_noparams();
if (result0 === null) {
result0 = parse_name_addr();
}
if (result0 !== null) {
result1 = [];
pos2 = pos;
result2 = parse_SEMI();
if (result2 !== null) {
result3 = parse_to_param();
if (result3 !== null) {
result2 = [result2, result3];
} else {
result2 = null;
pos = pos2;
}
} else {
result2 = null;
pos = pos2;
}
while (result2 !== null) {
result1.push(result2);
pos2 = pos;
result2 = parse_SEMI();
if (result2 !== null) {
result3 = parse_to_param();
if (result3 !== null) {
result2 = [result2, result3];
} else {
result2 = null;
pos = pos2;
}
} else {
result2 = null;
pos = pos2;
}
}
if (result1 !== null) {
result0 = [result0, result1];
} else {
result0 = null;
pos = pos1;
}
} else {
result0 = null;
pos = pos1;
}
if (result0 !== null) {
result0 = function (offset) {
var tag = data.tag;
try {
data = new NameAddrHeader(data.uri, data.display_name, data.params);
if (tag) {
data.setParam('tag', tag);
}
} catch (e) {
data = -1;
}
}(pos0);
}
if (result0 === null) {
pos = pos0;
}
return result0;
}
function parse_to_param() {
var result0;
result0 = parse_tag_param();
if (result0 === null) {
result0 = parse_generic_param();
}
return result0;
}
function parse_Via() {
var result0, result1, result2, result3;
var pos0, pos1;
pos0 = pos;
result0 = parse_via_param();
if (result0 !== null) {
result1 = [];
pos1 = pos;
result2 = parse_COMMA();
if (result2 !== null) {
result3 = parse_via_param();
if (result3 !== null) {
result2 = [result2, result3];
} else {
result2 = null;
pos = pos1;
}
} else {
result2 = null;
pos = pos1;
}
while (result2 !== null) {
result1.push(result2);
pos1 = pos;
result2 = parse_COMMA();
if (result2 !== null) {
result3 = parse_via_param();
if (result3 !== null) {
result2 = [result2, result3];
} else {
result2 = null;
pos = pos1;
}
} else {
result2 = null;
pos = pos1;
}
}
if (result1 !== null) {
result0 = [result0, result1];
} else {
result0 = null;
pos = pos0;
}
} else {
result0 = null;
pos = pos0;
}
return result0;
}
function parse_via_param() {
var result0, result1, result2, result3, result4, result5;
var pos0, pos1;
pos0 = pos;
result0 = parse_sent_protocol();
if (result0 !== null) {
result1 = parse_LWS();
if (result1 !== null) {
result2 = parse_sent_by();
if (result2 !== null) {
result3 = [];
pos1 = pos;
result4 = parse_SEMI();
if (result4 !== null) {
result5 = parse_via_params();
if (result5 !== null) {
result4 = [result4, result5];
} else {
result4 = null;
pos = pos1;
}
} else {
result4 = null;
pos = pos1;
}
while (result4 !== null) {
result3.push(result4);
pos1 = pos;
result4 = parse_SEMI();
if (result4 !== null) {
result5 = parse_via_params();
if (result5 !== null) {
result4 = [result4, result5];
} else {
result4 = null;
pos = pos1;
}
} else {
result4 = null;
pos = pos1;
}
}
if (result3 !== null) {
result0 = [result0, result1, result2, result3];
} else {
result0 = null;
pos = pos0;
}
} else {
result0 = null;
pos = pos0;
}
} else {
result0 = null;
pos = pos0;
}
} else {
result0 = null;
pos = pos0;
}
return result0;
}
function parse_via_params() {
var result0;
result0 = parse_via_ttl();
if (result0 === null) {
result0 = parse_via_maddr();
if (result0 === null) {
result0 = parse_via_received();
if (result0 === null) {
result0 = parse_via_branch();
if (result0 === null) {
result0 = parse_response_port();
if (result0 === null) {
result0 = parse_generic_param();
}
}
}
}
}
return result0;
}
function parse_via_ttl() {
var result0, result1, result2;
var pos0, pos1;
pos0 = pos;
pos1 = pos;
if (input.substr(pos, 3).toLowerCase() === "ttl") {
result0 = input.substr(pos, 3);
pos += 3;
} else {
result0 = null;
if (reportFailures === 0) {
matchFailed("\"ttl\"");
}
}
if (result0 !== null) {
result1 = parse_EQUAL();
if (result1 !== null) {
result2 = parse_ttl();
if (result2 !== null) {
result0 = [result0, result1, result2];
} else {
result0 = null;
pos = pos1;
}
} else {
result0 = null;
pos = pos1;
}
} else {
result0 = null;
pos = pos1;
}
if (result0 !== null) {
result0 = function (offset, via_ttl_value) {
data.ttl = via_ttl_value;
}(pos0, result0[2]);
}
if (result0 === null) {
pos = pos0;
}
return result0;
}
function parse_via_maddr() {
var result0, result1, result2;
var pos0, pos1;
pos0 = pos;
pos1 = pos;
if (input.substr(pos, 5).toLowerCase() === "maddr") {
result0 = input.substr(pos, 5);
pos += 5;
} else {
result0 = null;
if (reportFailures === 0) {
matchFailed("\"maddr\"");
}
}
if (result0 !== null) {
result1 = parse_EQUAL();
if (result1 !== null) {
result2 = parse_host();
if (result2 !== null) {
result0 = [result0, result1, result2];
} else {
result0 = null;
pos = pos1;
}
} else {
result0 = null;
pos = pos1;
}
} else {
result0 = null;
pos = pos1;
}
if (result0 !== null) {
result0 = function (offset, via_maddr) {
data.maddr = via_maddr;
}(pos0, result0[2]);
}
if (result0 === null) {
pos = pos0;
}
return result0;
}
function parse_via_received() {
var result0, result1, result2;
var pos0, pos1;
pos0 = pos;
pos1 = pos;
if (input.substr(pos, 8).toLowerCase() === "received") {
result0 = input.substr(pos, 8);
pos += 8;
} else {
result0 = null;
if (reportFailures === 0) {
matchFailed("\"received\"");
}
}
if (result0 !== null) {
result1 = parse_EQUAL();
if (result1 !== null) {
result2 = parse_IPv4address();
if (result2 === null) {
result2 = parse_IPv6address();
}
if (result2 !== null) {
result0 = [result0, result1, result2];
} else {
result0 = null;
pos = pos1;
}
} else {
result0 = null;
pos = pos1;
}
} else {
result0 = null;
pos = pos1;
}
if (result0 !== null) {
result0 = function (offset, via_received) {
data.received = via_received;
}(pos0, result0[2]);
}
if (result0 === null) {
pos = pos0;
}
return result0;
}
function parse_via_branch() {
var result0, result1, result2;
var pos0, pos1;
pos0 = pos;
pos1 = pos;
if (input.substr(pos, 6).toLowerCase() === "branch") {
result0 = input.substr(pos, 6);
pos += 6;
} else {
result0 = null;
if (reportFailures === 0) {
matchFailed("\"branch\"");
}
}
if (result0 !== null) {
result1 = parse_EQUAL();
if (result1 !== null) {
result2 = parse_token();
if (result2 !== null) {
result0 = [result0, result1, result2];
} else {
result0 = null;
pos = pos1;
}
} else {
result0 = null;
pos = pos1;
}
} else {
result0 = null;
pos = pos1;
}
if (result0 !== null) {
result0 = function (offset, via_branch) {
data.branch = via_branch;
}(pos0, result0[2]);
}
if (result0 === null) {
pos = pos0;
}
return result0;
}
function parse_response_port() {
var result0, result1, result2;
var pos0, pos1;
pos0 = pos;
if (input.substr(pos, 5).toLowerCase() === "rport") {
result0 = input.substr(pos, 5);
pos += 5;
} else {
result0 = null;
if (reportFailures === 0) {
matchFailed("\"rport\"");
}
}
if (result0 !== null) {
pos1 = pos;
result1 = parse_EQUAL();
if (result1 !== null) {
result2 = parse_rport();
if (result2 !== null) {
result1 = [result1, result2];
} else {
result1 = null;
pos = pos1;
}
} else {
result1 = null;
pos = pos1;
}
result1 = result1 !== null ? result1 : "";
if (result1 !== null) {
result0 = [result0, result1];
} else {
result0 = null;
pos = pos0;
}
} else {
result0 = null;
pos = pos0;
}
return result0;
}
function parse_rport() {
var result0, result1, result2, result3, result4;
var pos0, pos1;
pos0 = pos;
pos1 = pos;
result0 = parse_DIGIT();
result0 = result0 !== null ? result0 : "";
if (result0 !== null) {
result1 = parse_DIGIT();
result1 = result1 !== null ? result1 : "";
if (result1 !== null) {
result2 = parse_DIGIT();
result2 = result2 !== null ? result2 : "";
if (result2 !== null) {
result3 = parse_DIGIT();
result3 = result3 !== null ? result3 : "";
if (result3 !== null) {
result4 = parse_DIGIT();
result4 = result4 !== null ? result4 : "";
if (result4 !== null) {
result0 = [result0, result1, result2, result3, result4];
} else {
result0 = null;
pos = pos1;
}
} else {
result0 = null;
pos = pos1;
}
} else {
result0 = null;
pos = pos1;
}
} else {
result0 = null;
pos = pos1;
}
} else {
result0 = null;
pos = pos1;
}
if (result0 !== null) {
result0 = function (offset, rport) {
data.rport = parseInt(rport.join(''));
}(pos0, result0);
}
if (result0 === null) {
pos = pos0;
}
return result0;
}
function parse_sent_protocol() {
var result0, result1, result2, result3, result4;
var pos0;
pos0 = pos;
result0 = parse_protocol_name();
if (result0 !== null) {
result1 = parse_SLASH();
if (result1 !== null) {
result2 = parse_token();
if (result2 !== null) {
result3 = parse_SLASH();
if (result3 !== null) {
result4 = parse_transport();
if (result4 !== null) {
result0 = [result0, result1, result2, result3, result4];
} else {
result0 = null;
pos = pos0;
}
} else {
result0 = null;
pos = pos0;
}
} else {
result0 = null;
pos = pos0;
}
} else {
result0 = null;
pos = pos0;
}
} else {
result0 = null;
pos = pos0;
}
return result0;
}
function parse_protocol_name() {
var result0;
var pos0;
pos0 = pos;
if (input.substr(pos, 3).toLowerCase() === "sip") {
result0 = input.substr(pos, 3);
pos += 3;
} else {
result0 = null;
if (reportFailures === 0) {
matchFailed("\"SIP\"");
}
}
if (result0 === null) {
result0 = parse_token();
}
if (result0 !== null) {
result0 = function (offset, via_protocol) {
data.protocol = via_protocol;
}(pos0, result0);
}
if (result0 === null) {
pos = pos0;
}
return result0;
}
function parse_transport() {
var result0;
var pos0;
pos0 = pos;
if (input.substr(pos, 3).toLowerCase() === "udp") {
result0 = input.substr(pos, 3);
pos += 3;
} else {
result0 = null;
if (reportFailures === 0) {
matchFailed("\"UDP\"");
}
}
if (result0 === null) {
if (input.substr(pos, 3).toLowerCase() === "tcp") {
result0 = input.substr(pos, 3);
pos += 3;
} else {
result0 = null;
if (reportFailures === 0) {
matchFailed("\"TCP\"");
}
}
if (result0 === null) {
if (input.substr(pos, 3).toLowerCase() === "tls") {
result0 = input.substr(pos, 3);
pos += 3;
} else {
result0 = null;
if (reportFailures === 0) {
matchFailed("\"TLS\"");
}
}
if (result0 === null) {
if (input.substr(pos, 4).toLowerCase() === "sctp") {
result0 = input.substr(pos, 4);
pos += 4;
} else {
result0 = null;
if (reportFailures === 0) {
matchFailed("\"SCTP\"");
}
}
if (result0 === null) {
result0 = parse_token();
}
}
}
}
if (result0 !== null) {
result0 = function (offset, via_transport) {
data.transport = via_transport;
}(pos0, result0);
}
if (result0 === null) {
pos = pos0;
}
return result0;
}
function parse_sent_by() {
var result0, result1, result2;
var pos0, pos1;
pos0 = pos;
result0 = parse_via_host();
if (result0 !== null) {
pos1 = pos;
result1 = parse_COLON();
if (result1 !== null) {
result2 = parse_via_port();
if (result2 !== null) {
result1 = [result1, result2];
} else {
result1 = null;
pos = pos1;
}
} else {
result1 = null;
pos = pos1;
}
result1 = result1 !== null ? result1 : "";
if (result1 !== null) {
result0 = [result0, result1];
} else {
result0 = null;
pos = pos0;
}
} else {
result0 = null;
pos = pos0;
}
return result0;
}
function parse_via_host() {
var result0;
var pos0;
pos0 = pos;
result0 = parse_IPv4address();
if (result0 === null) {
result0 = parse_IPv6reference();
if (result0 === null) {
result0 = parse_hostname();
}
}
if (result0 !== null) {
result0 = function (offset) {
data.host = input.substring(pos, offset);
}(pos0);
}
if (result0 === null) {
pos = pos0;
}
return result0;
}
function parse_via_port() {
var result0, result1, result2, result3, result4;
var pos0, pos1;
pos0 = pos;
pos1 = pos;
result0 = parse_DIGIT();
result0 = result0 !== null ? result0 : "";
if (result0 !== null) {
result1 = parse_DIGIT();
result1 = result1 !== null ? result1 : "";
if (result1 !== null) {
result2 = parse_DIGIT();
result2 = result2 !== null ? result2 : "";
if (result2 !== null) {
result3 = parse_DIGIT();
result3 = result3 !== null ? result3 : "";
if (result3 !== null) {
result4 = parse_DIGIT();
result4 = result4 !== null ? result4 : "";
if (result4 !== null) {
result0 = [result0, result1, result2, result3, result4];
} else {
result0 = null;
pos = pos1;
}
} else {
result0 = null;
pos = pos1;
}
} else {
result0 = null;
pos = pos1;
}
} else {
result0 = null;
pos = pos1;
}
} else {
result0 = null;
pos = pos1;
}
if (result0 !== null) {
result0 = function (offset, via_sent_by_port) {
data.port = parseInt(via_sent_by_port.join(''));
}(pos0, result0);
}
if (result0 === null) {
pos = pos0;
}
return result0;
}
function parse_ttl() {
var result0, result1, result2;
var pos0, pos1;
pos0 = pos;
pos1 = pos;
result0 = parse_DIGIT();
if (result0 !== null) {
result1 = parse_DIGIT();
result1 = result1 !== null ? result1 : "";
if (result1 !== null) {
result2 = parse_DIGIT();
result2 = result2 !== null ? result2 : "";
if (result2 !== null) {
result0 = [result0, result1, result2];
} else {
result0 = null;
pos = pos1;
}
} else {
result0 = null;
pos = pos1;
}
} else {
result0 = null;
pos = pos1;
}
if (result0 !== null) {
result0 = function (offset, ttl) {
return parseInt(ttl.join(''));
}(pos0, result0);
}
if (result0 === null) {
pos = pos0;
}
return result0;
}
function parse_WWW_Authenticate() {
var result0;
result0 = parse_challenge();
return result0;
}
function parse_Session_Expires() {
var result0, result1, result2, result3;
var pos0, pos1;
pos0 = pos;
result0 = parse_s_e_expires();
if (result0 !== null) {
result1 = [];
pos1 = pos;
result2 = parse_SEMI();
if (result2 !== null) {
result3 = parse_s_e_params();
if (result3 !== null) {
result2 = [result2, result3];
} else {
result2 = null;
pos = pos1;
}
} else {
result2 = null;
pos = pos1;
}
while (result2 !== null) {
result1.push(result2);
pos1 = pos;
result2 = parse_SEMI();
if (result2 !== null) {
result3 = parse_s_e_params();
if (result3 !== null) {
result2 = [result2, result3];
} else {
result2 = null;
pos = pos1;
}
} else {
result2 = null;
pos = pos1;
}
}
if (result1 !== null) {
result0 = [result0, result1];
} else {
result0 = null;
pos = pos0;
}
} else {
result0 = null;
pos = pos0;
}
return result0;
}
function parse_s_e_expires() {
var result0;
var pos0;
pos0 = pos;
result0 = parse_delta_seconds();
if (result0 !== null) {
result0 = function (offset, expires) {
data.expires = expires;
}(pos0, result0);
}
if (result0 === null) {
pos = pos0;
}
return result0;
}
function parse_s_e_params() {
var result0;
result0 = parse_s_e_refresher();
if (result0 === null) {
result0 = parse_generic_param();
}
return result0;
}
function parse_s_e_refresher() {
var result0, result1, result2;
var pos0, pos1;
pos0 = pos;
pos1 = pos;
if (input.substr(pos, 9).toLowerCase() === "refresher") {
result0 = input.substr(pos, 9);
pos += 9;
} else {
result0 = null;
if (reportFailures === 0) {
matchFailed("\"refresher\"");
}
}
if (result0 !== null) {
result1 = parse_EQUAL();
if (result1 !== null) {
if (input.substr(pos, 3).toLowerCase() === "uac") {
result2 = input.substr(pos, 3);
pos += 3;
} else {
result2 = null;
if (reportFailures === 0) {
matchFailed("\"uac\"");
}
}
if (result2 === null) {
if (input.substr(pos, 3).toLowerCase() === "uas") {
result2 = input.substr(pos, 3);
pos += 3;
} else {
result2 = null;
if (reportFailures === 0) {
matchFailed("\"uas\"");
}
}
}
if (result2 !== null) {
result0 = [result0, result1, result2];
} else {
result0 = null;
pos = pos1;
}
} else {
result0 = null;
pos = pos1;
}
} else {
result0 = null;
pos = pos1;
}
if (result0 !== null) {
result0 = function (offset, s_e_refresher_value) {
data.refresher = s_e_refresher_value.toLowerCase();
}(pos0, result0[2]);
}
if (result0 === null) {
pos = pos0;
}
return result0;
}
function parse_extension_header() {
var result0, result1, result2;
var pos0;
pos0 = pos;
result0 = parse_token();
if (result0 !== null) {
result1 = parse_HCOLON();
if (result1 !== null) {
result2 = parse_header_value();
if (result2 !== null) {
result0 = [result0, result1, result2];
} else {
result0 = null;
pos = pos0;
}
} else {
result0 = null;
pos = pos0;
}
} else {
result0 = null;
pos = pos0;
}
return result0;
}
function parse_header_value() {
var result0, result1;
result0 = [];
result1 = parse_TEXT_UTF8char();
if (result1 === null) {
result1 = parse_UTF8_CONT();
if (result1 === null) {
result1 = parse_LWS();
}
}
while (result1 !== null) {
result0.push(result1);
result1 = parse_TEXT_UTF8char();
if (result1 === null) {
result1 = parse_UTF8_CONT();
if (result1 === null) {
result1 = parse_LWS();
}
}
}
return result0;
}
function parse_message_body() {
var result0, result1;
result0 = [];
result1 = parse_OCTET();
while (result1 !== null) {
result0.push(result1);
result1 = parse_OCTET();
}
return result0;
}
function parse_uuid_URI() {
var result0, result1;
var pos0;
pos0 = pos;
if (input.substr(pos, 5) === "uuid:") {
result0 = "uuid:";
pos += 5;
} else {
result0 = null;
if (reportFailures === 0) {
matchFailed("\"uuid:\"");
}
}
if (result0 !== null) {
result1 = parse_uuid();
if (result1 !== null) {
result0 = [result0, result1];
} else {
result0 = null;
pos = pos0;
}
} else {
result0 = null;
pos = pos0;
}
return result0;
}
function parse_uuid() {
var result0, result1, result2, result3, result4, result5, result6, result7, result8;
var pos0, pos1;
pos0 = pos;
pos1 = pos;
result0 = parse_hex8();
if (result0 !== null) {
if (input.charCodeAt(pos) === 45) {
result1 = "-";
pos++;
} else {
result1 = null;
if (reportFailures === 0) {
matchFailed("\"-\"");
}
}
if (result1 !== null) {
result2 = parse_hex4();
if (result2 !== null) {
if (input.charCodeAt(pos) === 45) {
result3 = "-";
pos++;
} else {
result3 = null;
if (reportFailures === 0) {
matchFailed("\"-\"");
}
}
if (result3 !== null) {
result4 = parse_hex4();
if (result4 !== null) {
if (input.charCodeAt(pos) === 45) {
result5 = "-";
pos++;
} else {
result5 = null;
if (reportFailures === 0) {
matchFailed("\"-\"");
}
}
if (result5 !== null) {
result6 = parse_hex4();
if (result6 !== null) {
if (input.charCodeAt(pos) === 45) {
result7 = "-";
pos++;
} else {
result7 = null;
if (reportFailures === 0) {
matchFailed("\"-\"");
}
}
if (result7 !== null) {
result8 = parse_hex12();
if (result8 !== null) {
result0 = [result0, result1, result2, result3, result4, result5, result6, result7, result8];
} else {
result0 = null;
pos = pos1;
}
} else {
result0 = null;
pos = pos1;
}
} else {
result0 = null;
pos = pos1;
}
} else {
result0 = null;
pos = pos1;
}
} else {
result0 = null;
pos = pos1;
}
} else {
result0 = null;
pos = pos1;
}
} else {
result0 = null;
pos = pos1;
}
} else {
result0 = null;
pos = pos1;
}
} else {
result0 = null;
pos = pos1;
}
if (result0 !== null) {
result0 = function (offset, uuid) {
data = input.substring(pos + 5, offset);
}(pos0, result0[0]);
}
if (result0 === null) {
pos = pos0;
}
return result0;
}
function parse_hex4() {
var result0, result1, result2, result3;
var pos0;
pos0 = pos;
result0 = parse_HEXDIG();
if (result0 !== null) {
result1 = parse_HEXDIG();
if (result1 !== null) {
result2 = parse_HEXDIG();
if (result2 !== null) {
result3 = parse_HEXDIG();
if (result3 !== null) {
result0 = [result0, result1, result2, result3];
} else {
result0 = null;
pos = pos0;
}
} else {
result0 = null;
pos = pos0;
}
} else {
result0 = null;
pos = pos0;
}
} else {
result0 = null;
pos = pos0;
}
return result0;
}
function parse_hex8() {
var result0, result1;
var pos0;
pos0 = pos;
result0 = parse_hex4();
if (result0 !== null) {
result1 = parse_hex4();
if (result1 !== null) {
result0 = [result0, result1];
} else {
result0 = null;
pos = pos0;
}
} else {
result0 = null;
pos = pos0;
}
return result0;
}
function parse_hex12() {
var result0, result1, result2;
var pos0;
pos0 = pos;
result0 = parse_hex4();
if (result0 !== null) {
result1 = parse_hex4();
if (result1 !== null) {
result2 = parse_hex4();
if (result2 !== null) {
result0 = [result0, result1, result2];
} else {
result0 = null;
pos = pos0;
}
} else {
result0 = null;
pos = pos0;
}
} else {
result0 = null;
pos = pos0;
}
return result0;
}
function parse_Refer_To() {
var result0, result1, result2, result3;
var pos0, pos1, pos2;
pos0 = pos;
pos1 = pos;
result0 = parse_SIP_URI_noparams();
if (result0 === null) {
result0 = parse_name_addr();
}
if (result0 !== null) {
result1 = [];
pos2 = pos;
result2 = parse_SEMI();
if (result2 !== null) {
result3 = parse_generic_param();
if (result3 !== null) {
result2 = [result2, result3];
} else {
result2 = null;
pos = pos2;
}
} else {
result2 = null;
pos = pos2;
}
while (result2 !== null) {
result1.push(result2);
pos2 = pos;
result2 = parse_SEMI();
if (result2 !== null) {
result3 = parse_generic_param();
if (result3 !== null) {
result2 = [result2, result3];
} else {
result2 = null;
pos = pos2;
}
} else {
result2 = null;
pos = pos2;
}
}
if (result1 !== null) {
result0 = [result0, result1];
} else {
result0 = null;
pos = pos1;
}
} else {
result0 = null;
pos = pos1;
}
if (result0 !== null) {
result0 = function (offset) {
try {
data = new NameAddrHeader(data.uri, data.display_name, data.params);
} catch (e) {
data = -1;
}
}(pos0);
}
if (result0 === null) {
pos = pos0;
}
return result0;
}
function parse_Replaces() {
var result0, result1, result2, result3;
var pos0, pos1;
pos0 = pos;
result0 = parse_call_id();
if (result0 !== null) {
result1 = [];
pos1 = pos;
result2 = parse_SEMI();
if (result2 !== null) {
result3 = parse_replaces_param();
if (result3 !== null) {
result2 = [result2, result3];
} else {
result2 = null;
pos = pos1;
}
} else {
result2 = null;
pos = pos1;
}
while (result2 !== null) {
result1.push(result2);
pos1 = pos;
result2 = parse_SEMI();
if (result2 !== null) {
result3 = parse_replaces_param();
if (result3 !== null) {
result2 = [result2, result3];
} else {
result2 = null;
pos = pos1;
}
} else {
result2 = null;
pos = pos1;
}
}
if (result1 !== null) {
result0 = [result0, result1];
} else {
result0 = null;
pos = pos0;
}
} else {
result0 = null;
pos = pos0;
}
return result0;
}
function parse_call_id() {
var result0, result1, result2;
var pos0, pos1, pos2;
pos0 = pos;
pos1 = pos;
result0 = parse_word();
if (result0 !== null) {
pos2 = pos;
if (input.charCodeAt(pos) === 64) {
result1 = "@";
pos++;
} else {
result1 = null;
if (reportFailures === 0) {
matchFailed("\"@\"");
}
}
if (result1 !== null) {
result2 = parse_word();
if (result2 !== null) {
result1 = [result1, result2];
} else {
result1 = null;
pos = pos2;
}
} else {
result1 = null;
pos = pos2;
}
result1 = result1 !== null ? result1 : "";
if (result1 !== null) {
result0 = [result0, result1];
} else {
result0 = null;
pos = pos1;
}
} else {
result0 = null;
pos = pos1;
}
if (result0 !== null) {
result0 = function (offset) {
data.call_id = input.substring(pos, offset);
}(pos0);
}
if (result0 === null) {
pos = pos0;
}
return result0;
}
function parse_replaces_param() {
var result0;
result0 = parse_to_tag();
if (result0 === null) {
result0 = parse_from_tag();
if (result0 === null) {
result0 = parse_early_flag();
if (result0 === null) {
result0 = parse_generic_param();
}
}
}
return result0;
}
function parse_to_tag() {
var result0, result1, result2;
var pos0, pos1;
pos0 = pos;
pos1 = pos;
if (input.substr(pos, 6) === "to-tag") {
result0 = "to-tag";
pos += 6;
} else {
result0 = null;
if (reportFailures === 0) {
matchFailed("\"to-tag\"");
}
}
if (result0 !== null) {
result1 = parse_EQUAL();
if (result1 !== null) {
result2 = parse_token();
if (result2 !== null) {
result0 = [result0, result1, result2];
} else {
result0 = null;
pos = pos1;
}
} else {
result0 = null;
pos = pos1;
}
} else {
result0 = null;
pos = pos1;
}
if (result0 !== null) {
result0 = function (offset, to_tag) {
data.to_tag = to_tag;
}(pos0, result0[2]);
}
if (result0 === null) {
pos = pos0;
}
return result0;
}
function parse_from_tag() {
var result0, result1, result2;
var pos0, pos1;
pos0 = pos;
pos1 = pos;
if (input.substr(pos, 8) === "from-tag") {
result0 = "from-tag";
pos += 8;
} else {
result0 = null;
if (reportFailures === 0) {
matchFailed("\"from-tag\"");
}
}
if (result0 !== null) {
result1 = parse_EQUAL();
if (result1 !== null) {
result2 = parse_token();
if (result2 !== null) {
result0 = [result0, result1, result2];
} else {
result0 = null;
pos = pos1;
}
} else {
result0 = null;
pos = pos1;
}
} else {
result0 = null;
pos = pos1;
}
if (result0 !== null) {
result0 = function (offset, from_tag) {
data.from_tag = from_tag;
}(pos0, result0[2]);
}
if (result0 === null) {
pos = pos0;
}
return result0;
}
function parse_early_flag() {
var result0;
var pos0;
pos0 = pos;
if (input.substr(pos, 10) === "early-only") {
result0 = "early-only";
pos += 10;
} else {
result0 = null;
if (reportFailures === 0) {
matchFailed("\"early-only\"");
}
}
if (result0 !== null) {
result0 = function (offset) {
data.early_only = true;
}(pos0);
}
if (result0 === null) {
pos = pos0;
}
return result0;
}
function cleanupExpected(expected) {
expected.sort();
var lastExpected = null;
var cleanExpected = [];
for (var i = 0; i < expected.length; i++) {
if (expected[i] !== lastExpected) {
cleanExpected.push(expected[i]);
lastExpected = expected[i];
}
}
return cleanExpected;
}
function computeErrorPosition() {
/*
* The first idea was to use |String.split| to break the input up to the
* error position along newlines and derive the line and column from
* there. However IE's |split| implementation is so broken that it was
* enough to prevent it.
*/
var line = 1;
var column = 1;
var seenCR = false;
for (var i = 0; i < Math.max(pos, rightmostFailuresPos); i++) {
var ch = input.charAt(i);
if (ch === "\n") {
if (!seenCR) {
line++;
}
column = 1;
seenCR = false;
} else if (ch === "\r" || ch === "\u2028" || ch === "\u2029") {
line++;
column = 1;
seenCR = true;
} else {
column++;
seenCR = false;
}
}
return {
line: line,
column: column
};
}
var URI = require('./URI');
var NameAddrHeader = require('./NameAddrHeader');
var data = {};
var result = parseFunctions[startRule]();
/*
* The parser is now in one of the following three states:
*
* 1. The parser successfully parsed the whole input.
*
* - |result !== null|
* - |pos === input.length|
* - |rightmostFailuresExpected| may or may not contain something
*
* 2. The parser successfully parsed only a part of the input.
*
* - |result !== null|
* - |pos < input.length|
* - |rightmostFailuresExpected| may or may not contain something
*
* 3. The parser did not successfully parse any part of the input.
*
* - |result === null|
* - |pos === 0|
* - |rightmostFailuresExpected| contains at least one failure
*
* All code following this comment (including called functions) must
* handle these states.
*/
if (result === null || pos !== input.length) {
var offset = Math.max(pos, rightmostFailuresPos);
var found = offset < input.length ? input.charAt(offset) : null;
var errorPosition = computeErrorPosition();
new this.SyntaxError(cleanupExpected(rightmostFailuresExpected), found, offset, errorPosition.line, errorPosition.column);
return -1;
}
return data;
},
/* Returns the parser source code. */
toSource: function toSource() {
return this._source;
}
};
/* Thrown when a parser encounters a syntax error. */
result.SyntaxError = function (expected, found, offset, line, column) {
function buildMessage(expected, found) {
var expectedHumanized, foundHumanized;
switch (expected.length) {
case 0:
expectedHumanized = "end of input";
break;
case 1:
expectedHumanized = expected[0];
break;
default:
expectedHumanized = expected.slice(0, expected.length - 1).join(", ") + " or " + expected[expected.length - 1];
}
foundHumanized = found ? quote(found) : "end of input";
return "Expected " + expectedHumanized + " but " + foundHumanized + " found.";
}
this.name = "SyntaxError";
this.expected = expected;
this.found = found;
this.message = buildMessage(expected, found);
this.offset = offset;
this.line = line;
this.column = column;
};
result.SyntaxError.prototype = Error.prototype;
return result;
}();
},{"./NameAddrHeader":11,"./URI":27}],8:[function(require,module,exports){
"use strict";
var pkg = require('../package.json');
var C = require('./Constants');
var Exceptions = require('./Exceptions');
var Utils = require('./Utils');
var UA = require('./UA');
var URI = require('./URI');
var NameAddrHeader = require('./NameAddrHeader');
var Grammar = require('./Grammar');
var WebSocketInterface = require('./WebSocketInterface');
var debug = require('debug')('SimpleSIP');
debug('version %s', pkg.version);
/**
* Expose the SimpleSIP module.
*/
module.exports = {
C: C,
Exceptions: Exceptions,
Utils: Utils,
UA: UA,
URI: URI,
NameAddrHeader: NameAddrHeader,
WebSocketInterface: WebSocketInterface,
Grammar: Grammar,
// Expose the debug module.
debug: require('debug'),
get name() {
return pkg.title;
},
get version() {
return pkg.version;
}
};
},{"../package.json":40,"./Constants":2,"./Exceptions":6,"./Grammar":7,"./NameAddrHeader":11,"./UA":26,"./URI":27,"./Utils":28,"./WebSocketInterface":29,"debug":32}],9:[function(require,module,exports){
"use strict";
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }
var debug = require('debug');
var APP_NAME = 'SimpleSIP';
module.exports = /*#__PURE__*/function () {
function Logger(prefix) {
_classCallCheck(this, Logger);
if (prefix) {
this._debug = debug["default"]("".concat(APP_NAME, ":").concat(prefix));
this._warn = debug["default"]("".concat(APP_NAME, ":WARN:").concat(prefix));
this._error = debug["default"]("".concat(APP_NAME, ":ERROR:").concat(prefix));
} else {
this._debug = debug["default"](APP_NAME);
this._warn = debug["default"]("".concat(APP_NAME, ":WARN"));
this._error = debug["default"]("".concat(APP_NAME, ":ERROR"));
}
/* eslint-disable no-console */
this._debug.log = console.info.bind(console);
this._warn.log = console.warn.bind(console);
this._error.log = console.error.bind(console);
/* eslint-enable no-console */
}
_createClass(Logger, [{
key: "debug",
get: function get() {
return this._debug;
}
}, {
key: "warn",
get: function get() {
return this._warn;
}
}, {
key: "error",
get: function get() {
return this._error;
}
}]);
return Logger;
}();
},{"debug":32}],10:[function(require,module,exports){
"use strict";
function _typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); if (superClass) _setPrototypeOf(subClass, superClass); }
function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }
function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; }
function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === "object" || typeof call === "function")) { return call; } return _assertThisInitialized(self); }
function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; }
function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); return true; } catch (e) { return false; } }
function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }
var EventEmitter = require('events').EventEmitter;
var Logger = require('./Logger');
var SimpleSIP_C = require('./Constants');
var SIPMessage = require('./SIPMessage');
var Utils = require('./Utils');
var RequestSender = require('./RequestSender');
var Exceptions = require('./Exceptions');
var URI = require('./URI');
var logger = new Logger('Message');
module.exports = /*#__PURE__*/function (_EventEmitter) {
_inherits(Message, _EventEmitter);
var _super = _createSuper(Message);
function Message(ua) {
var _this;
_classCallCheck(this, Message);
_this = _super.call(this);
_this._ua = ua;
_this._request = null;
_this._closed = false;
_this._direction = null;
_this._local_identity = null;
_this._remote_identity = null; // Whether an incoming message has been replied.
_this._is_replied = false; // Custom message empty object for high level use.
_this._data = {};
return _this;
}
_createClass(Message, [{
key: "send",
value: function send(target, body) {
var _this2 = this;
var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
var originalTarget = target;
if (target === undefined || body === undefined) {
throw new TypeError('Not enough arguments');
} // Check target validity.
target = this._ua.normalizeTarget(target);
if (!target) {
throw new TypeError("Invalid target: ".concat(originalTarget));
} // Get call options.
var extraHeaders = Utils.cloneArray(options.extraHeaders);
var eventHandlers = Utils.cloneObject(options.eventHandlers);
var contentType = options.contentType || 'text/plain';
var requestParams = {};
if (options.fromUserName) {
requestParams.from_uri = new URI('sip', options.fromUserName, this._ua.configuration.uri.host);
extraHeaders.push("P-Preferred-Identity: ".concat(this._ua.configuration.uri.toString()));
}
if (options.fromDisplayName) {
requestParams.from_display_name = options.fromDisplayName;
} // Set event handlers.
for (var event in eventHandlers) {
if (Object.prototype.hasOwnProperty.call(eventHandlers, event)) {
this.on(event, eventHandlers[event]);
}
}
extraHeaders.push("Content-Type: ".concat(contentType));
this._request = new SIPMessage.OutgoingRequest(SimpleSIP_C.MESSAGE, target, this._ua, requestParams, extraHeaders);
if (body) {
this._request.body = body;
}
var request_sender = new RequestSender(this._ua, this._request, {
onRequestTimeout: function onRequestTimeout() {
_this2._onRequestTimeout();
},
onTransportError: function onTransportError() {
_this2._onTransportError();
},
onReceiveResponse: function onReceiveResponse(response) {
_this2._receiveResponse(response);
}
});
this._newMessage('local', this._request);
request_sender.send();
}
}, {
key: "init_incoming",
value: function init_incoming(request) {
this._request = request;
this._newMessage('remote', request); // Reply with a 200 OK if the user didn't reply.
if (!this._is_replied) {
this._is_replied = true;
request.reply(200);
}
this._close();
}
/**
* Accept the incoming Message
* Only valid for incoming Messages
*/
}, {
key: "accept",
value: function accept() {
var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
var extraHeaders = Utils.cloneArray(options.extraHeaders);
var body = options.body;
if (this._direction !== 'incoming') {
throw new Exceptions.NotSupportedError('"accept" not supported for outgoing Message');
}
if (this._is_replied) {
throw new Error('incoming Message already replied');
}
this._is_replied = true;
this._request.reply(200, null, extraHeaders, body);
}
/**
* Reject the incoming Message
* Only valid for incoming Messages
*/
}, {
key: "reject",
value: function reject() {
var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
var status_code = options.status_code || 480;
var reason_phrase = options.reason_phrase;
var extraHeaders = Utils.cloneArray(options.extraHeaders);
var body = options.body;
if (this._direction !== 'incoming') {
throw new Exceptions.NotSupportedError('"reject" not supported for outgoing Message');
}
if (this._is_replied) {
throw new Error('incoming Message already replied');
}
if (status_code < 300 || status_code >= 700) {
throw new TypeError("Invalid status_code: ".concat(status_code));
}
this._is_replied = true;
this._request.reply(status_code, reason_phrase, extraHeaders, body);
}
}, {
key: "_receiveResponse",
value: function _receiveResponse(response) {
if (this._closed) {
return;
}
switch (true) {
case /^1[0-9]{2}$/.test(response.status_code):
// Ignore provisional responses.
break;
case /^2[0-9]{2}$/.test(response.status_code):
this._succeeded('remote', response);
break;
default:
{
var cause = Utils.sipErrorCause(response.status_code);
this._failed('remote', response, cause);
break;
}
}
}
}, {
key: "_onRequestTimeout",
value: function _onRequestTimeout() {
if (this._closed) {
return;
}
this._failed('system', null, SimpleSIP_C.causes.REQUEST_TIMEOUT);
}
}, {
key: "_onTransportError",
value: function _onTransportError() {
if (this._closed) {
return;
}
this._failed('system', null, SimpleSIP_C.causes.CONNECTION_ERROR);
}
}, {
key: "_close",
value: function _close() {
this._closed = true;
this._ua.destroyMessage(this);
}
/**
* Internal Callbacks
*/
}, {
key: "_newMessage",
value: function _newMessage(originator, request) {
if (originator === 'remote') {
this._direction = 'incoming';
this._local_identity = request.to;
this._remote_identity = request.from;
} else if (originator === 'local') {
this._direction = 'outgoing';
this._local_identity = request.from;
this._remote_identity = request.to;
}
this._ua.newMessage(this, {
originator: originator,
message: this,
request: request
});
}
}, {
key: "_failed",
value: function _failed(originator, response, cause) {
logger.debug('MESSAGE failed');
this._close();
logger.debug('emit "failed"');
this.emit('failed', {
originator: originator,
response: response || null,
cause: cause
});
}
}, {
key: "_succeeded",
value: function _succeeded(originator, response) {
logger.debug('MESSAGE succeeded');
this._close();
logger.debug('emit "succeeded"');
this.emit('succeeded', {
originator: originator,
response: response
});
}
}, {
key: "direction",
get: function get() {
return this._direction;
}
}, {
key: "local_identity",
get: function get() {
return this._local_identity;
}
}, {
key: "remote_identity",
get: function get() {
return this._remote_identity;
}
}]);
return Message;
}(EventEmitter);
},{"./Constants":2,"./Exceptions":6,"./Logger":9,"./RequestSender":20,"./SIPMessage":21,"./URI":27,"./Utils":28,"events":31}],11:[function(require,module,exports){
"use strict";
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }
var URI = require('./URI');
var Grammar = require('./Grammar');
module.exports = /*#__PURE__*/function () {
_createClass(NameAddrHeader, null, [{
key: "parse",
/**
* Parse the given string and returns a NameAddrHeader instance or undefined if
* it is an invalid NameAddrHeader.
*/
value: function parse(name_addr_header) {
name_addr_header = Grammar.parse(name_addr_header, 'Name_Addr_Header');
if (name_addr_header !== -1) {
return name_addr_header;
} else {
return undefined;
}
}
}]);
function NameAddrHeader(uri, display_name, parameters) {
_classCallCheck(this, NameAddrHeader);
// Checks.
if (!uri || !(uri instanceof URI)) {
throw new TypeError('missing or invalid "uri" parameter');
} // Initialize parameters.
this._uri = uri;
this._parameters = {};
this.display_name = display_name;
for (var param in parameters) {
if (Object.prototype.hasOwnProperty.call(parameters, param)) {
this.setParam(param, parameters[param]);
}
}
}
_createClass(NameAddrHeader, [{
key: "setParam",
value: function setParam(key, value) {
if (key) {
this._parameters[key.toLowerCase()] = typeof value === 'undefined' || value === null ? null : value.toString();
}
}
}, {
key: "getParam",
value: function getParam(key) {
if (key) {
return this._parameters[key.toLowerCase()];
}
}
}, {
key: "hasParam",
value: function hasParam(key) {
if (key) {
return this._parameters.hasOwnProperty(key.toLowerCase()) && true || false;
}
}
}, {
key: "deleteParam",
value: function deleteParam(parameter) {
parameter = parameter.toLowerCase();
if (this._parameters.hasOwnProperty(parameter)) {
var value = this._parameters[parameter];
delete this._parameters[parameter];
return value;
}
}
}, {
key: "clearParams",
value: function clearParams() {
this._parameters = {};
}
}, {
key: "clone",
value: function clone() {
return new NameAddrHeader(this._uri.clone(), this._display_name, JSON.parse(JSON.stringify(this._parameters)));
}
}, {
key: "_quote",
value: function _quote(str) {
return str.replace(/\\/g, '\\\\').replace(/"/g, '\\"');
}
}, {
key: "toString",
value: function toString() {
var body = this._display_name ? "\"".concat(this._quote(this._display_name), "\" ") : '';
body += "<".concat(this._uri.toString(), ">");
for (var parameter in this._parameters) {
if (Object.prototype.hasOwnProperty.call(this._parameters, parameter)) {
body += ";".concat(parameter);
if (this._parameters[parameter] !== null) {
body += "=".concat(this._parameters[parameter]);
}
}
}
return body;
}
}, {
key: "uri",
get: function get() {
return this._uri;
}
}, {
key: "display_name",
get: function get() {
return this._display_name;
},
set: function set(value) {
this._display_name = value === 0 ? '0' : value;
}
}]);
return NameAddrHeader;
}();
},{"./Grammar":7,"./URI":27}],12:[function(require,module,exports){
"use strict";
function _typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); if (superClass) _setPrototypeOf(subClass, superClass); }
function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }
function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; }
function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === "object" || typeof call === "function")) { return call; } return _assertThisInitialized(self); }
function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; }
function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); return true; } catch (e) { return false; } }
function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }
var EventEmitter = require('events').EventEmitter;
var Logger = require('./Logger');
var SimpleSIP_C = require('./Constants');
var SIPMessage = require('./SIPMessage');
var Utils = require('./Utils');
var RequestSender = require('./RequestSender');
var Exceptions = require('./Exceptions');
var logger = new Logger('Options');
module.exports = /*#__PURE__*/function (_EventEmitter) {
_inherits(Options, _EventEmitter);
var _super = _createSuper(Options);
function Options(ua) {
var _this;
_classCallCheck(this, Options);
_this = _super.call(this);
_this._ua = ua;
_this._request = null;
_this._closed = false;
_this._direction = null;
_this._local_identity = null;
_this._remote_identity = null; // Whether an incoming message has been replied.
_this._is_replied = false; // Custom message empty object for high level use.
_this._data = {};
return _this;
}
_createClass(Options, [{
key: "send",
value: function send(target, body) {
var _this2 = this;
var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
var originalTarget = target;
if (target === undefined) {
throw new TypeError('A target is required for OPTIONS');
} // Check target validity.
target = this._ua.normalizeTarget(target);
if (!target) {
throw new TypeError("Invalid target: ".concat(originalTarget));
} // Get call options.
var extraHeaders = Utils.cloneArray(options.extraHeaders);
var eventHandlers = Utils.cloneObject(options.eventHandlers);
var contentType = options.contentType || 'application/sdp'; // Set event handlers.
for (var event in eventHandlers) {
if (Object.prototype.hasOwnProperty.call(eventHandlers, event)) {
this.on(event, eventHandlers[event]);
}
}
extraHeaders.push("Content-Type: ".concat(contentType));
this._request = new SIPMessage.OutgoingRequest(SimpleSIP_C.OPTIONS, target, this._ua, null, extraHeaders);
if (body) {
this._request.body = body;
}
var request_sender = new RequestSender(this._ua, this._request, {
onRequestTimeout: function onRequestTimeout() {
_this2._onRequestTimeout();
},
onTransportError: function onTransportError() {
_this2._onTransportError();
},
onReceiveResponse: function onReceiveResponse(response) {
_this2._receiveResponse(response);
}
});
this._newOptions('local', this._request);
request_sender.send();
}
}, {
key: "init_incoming",
value: function init_incoming(request) {
this._request = request;
this._newOptions('remote', request); // Reply with a 200 OK if the user didn't reply.
if (!this._is_replied) {
this._is_replied = true;
request.reply(200);
}
this._close();
}
/**
* Accept the incoming Options
* Only valid for incoming Options
*/
}, {
key: "accept",
value: function accept() {
var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
var extraHeaders = Utils.cloneArray(options.extraHeaders);
var body = options.body;
if (this._direction !== 'incoming') {
throw new Exceptions.NotSupportedError('"accept" not supported for outgoing Options');
}
if (this._is_replied) {
throw new Error('incoming Options already replied');
}
this._is_replied = true;
this._request.reply(200, null, extraHeaders, body);
}
/**
* Reject the incoming Options
* Only valid for incoming Options
*/
}, {
key: "reject",
value: function reject() {
var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
var status_code = options.status_code || 480;
var reason_phrase = options.reason_phrase;
var extraHeaders = Utils.cloneArray(options.extraHeaders);
var body = options.body;
if (this._direction !== 'incoming') {
throw new Exceptions.NotSupportedError('"reject" not supported for outgoing Options');
}
if (this._is_replied) {
throw new Error('incoming Options already replied');
}
if (status_code < 300 || status_code >= 700) {
throw new TypeError("Invalid status_code: ".concat(status_code));
}
this._is_replied = true;
this._request.reply(status_code, reason_phrase, extraHeaders, body);
}
}, {
key: "_receiveResponse",
value: function _receiveResponse(response) {
if (this._closed) {
return;
}
switch (true) {
case /^1[0-9]{2}$/.test(response.status_code):
// Ignore provisional responses.
break;
case /^2[0-9]{2}$/.test(response.status_code):
this._succeeded('remote', response);
break;
default:
{
var cause = Utils.sipErrorCause(response.status_code);
this._failed('remote', response, cause);
break;
}
}
}
}, {
key: "_onRequestTimeout",
value: function _onRequestTimeout() {
if (this._closed) {
return;
}
this._failed('system', null, SimpleSIP_C.causes.REQUEST_TIMEOUT);
}
}, {
key: "_onTransportError",
value: function _onTransportError() {
if (this._closed) {
return;
}
this._failed('system', null, SimpleSIP_C.causes.CONNECTION_ERROR);
}
}, {
key: "_close",
value: function _close() {
this._closed = true;
this._ua.destroyMessage(this);
}
/**
* Internal Callbacks
*/
}, {
key: "_newOptions",
value: function _newOptions(originator, request) {
if (originator === 'remote') {
this._direction = 'incoming';
this._local_identity = request.to;
this._remote_identity = request.from;
} else if (originator === 'local') {
this._direction = 'outgoing';
this._local_identity = request.from;
this._remote_identity = request.to;
}
this._ua.newOptions(this, {
originator: originator,
message: this,
request: request
});
}
}, {
key: "_failed",
value: function _failed(originator, response, cause) {
logger.debug('OPTIONS failed');
this._close();
logger.debug('emit "failed"');
this.emit('failed', {
originator: originator,
response: response || null,
cause: cause
});
}
}, {
key: "_succeeded",
value: function _succeeded(originator, response) {
logger.debug('OPTIONS succeeded');
this._close();
logger.debug('emit "succeeded"');
this.emit('succeeded', {
originator: originator,
response: response
});
}
}, {
key: "direction",
get: function get() {
return this._direction;
}
}, {
key: "local_identity",
get: function get() {
return this._local_identity;
}
}, {
key: "remote_identity",
get: function get() {
return this._remote_identity;
}
}]);
return Options;
}(EventEmitter);
},{"./Constants":2,"./Exceptions":6,"./Logger":9,"./RequestSender":20,"./SIPMessage":21,"./Utils":28,"events":31}],13:[function(require,module,exports){
"use strict";
function _createForOfIteratorHelper(o, allowArrayLike) { var it; if (typeof Symbol === "undefined" || o[Symbol.iterator] == null) { if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = o[Symbol.iterator](); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it["return"] != null) it["return"](); } finally { if (didErr) throw err; } } }; }
function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }
var Logger = require('./Logger');
var Grammar = require('./Grammar');
var SIPMessage = require('./SIPMessage');
var logger = new Logger('Parser');
/**
* Parse SIP Message
*/
exports.parseMessage = function (data, ua) {
var message;
var bodyStart;
var headerEnd = data.indexOf('\r\n');
if (headerEnd === -1) {
logger.warn('parseMessage() | no CRLF found, not a SIP message');
return;
} // Parse first line. Check if it is a Request or a Reply.
var firstLine = data.substring(0, headerEnd);
var parsed = Grammar.parse(firstLine, 'Request_Response');
if (parsed === -1) {
logger.warn("parseMessage() | error parsing first line of SIP message: \"".concat(firstLine, "\""));
return;
} else if (!parsed.status_code) {
message = new SIPMessage.IncomingRequest(ua);
message.method = parsed.method;
message.ruri = parsed.uri;
} else {
message = new SIPMessage.IncomingResponse();
message.status_code = parsed.status_code;
message.reason_phrase = parsed.reason_phrase;
}
message.data = data;
var headerStart = headerEnd + 2;
/* Loop over every line in data. Detect the end of each header and parse
* it or simply add to the headers collection.
*/
while (true) {
headerEnd = getHeader(data, headerStart); // The SIP message has normally finished.
if (headerEnd === -2) {
bodyStart = headerStart + 2;
break;
} // Data.indexOf returned -1 due to a malformed message.
else if (headerEnd === -1) {
logger.warn('parseMessage() | malformed message');
return;
}
parsed = parseHeader(message, data, headerStart, headerEnd);
if (parsed !== true) {
logger.warn('parseMessage() |', parsed.error);
return;
}
headerStart = headerEnd + 2;
}
/* RFC3261 18.3.
* If there are additional bytes in the transport packet
* beyond the end of the body, they MUST be discarded.
*/
if (message.hasHeader('content-length')) {
var contentLength = message.getHeader('content-length');
message.body = data.substr(bodyStart, contentLength);
} else {
message.body = data.substring(bodyStart);
}
return message;
};
/**
* Extract and parse every header of a SIP message.
*/
function getHeader(data, headerStart) {
// 'start' position of the header.
var start = headerStart; // 'end' position of the header.
var end = 0; // 'partial end' position of the header.
var partialEnd = 0; // End of message.
if (data.substring(start, start + 2).match(/(^\r\n)/)) {
return -2;
}
while (end === 0) {
// Partial End of Header.
partialEnd = data.indexOf('\r\n', start); // 'indexOf' returns -1 if the value to be found never occurs.
if (partialEnd === -1) {
return partialEnd;
}
if (!data.substring(partialEnd + 2, partialEnd + 4).match(/(^\r\n)/) && data.charAt(partialEnd + 2).match(/(^\s+)/)) {
// Not the end of the message. Continue from the next position.
start = partialEnd + 2;
} else {
end = partialEnd;
}
}
return end;
}
function parseHeader(message, data, headerStart, headerEnd) {
var parsed;
var hcolonIndex = data.indexOf(':', headerStart);
var headerName = data.substring(headerStart, hcolonIndex).trim();
var headerValue = data.substring(hcolonIndex + 1, headerEnd).trim(); // If header-field is well-known, parse it.
switch (headerName.toLowerCase()) {
case 'via':
case 'v':
message.addHeader('via', headerValue);
if (message.getHeaders('via').length === 1) {
parsed = message.parseHeader('Via');
if (parsed) {
message.via = parsed;
message.via_branch = parsed.branch;
}
} else {
parsed = 0;
}
break;
case 'from':
case 'f':
message.setHeader('from', headerValue);
parsed = message.parseHeader('from');
if (parsed) {
message.from = parsed;
message.from_tag = parsed.getParam('tag');
}
break;
case 'to':
case 't':
message.setHeader('to', headerValue);
parsed = message.parseHeader('to');
if (parsed) {
message.to = parsed;
message.to_tag = parsed.getParam('tag');
}
break;
case 'record-route':
parsed = Grammar.parse(headerValue, 'Record_Route');
if (parsed === -1) {
parsed = undefined;
} else {
var _iterator = _createForOfIteratorHelper(parsed),
_step;
try {
for (_iterator.s(); !(_step = _iterator.n()).done;) {
var header = _step.value;
message.addHeader('record-route', headerValue.substring(header.possition, header.offset));
message.headers['Record-Route'][message.getHeaders('record-route').length - 1].parsed = header.parsed;
}
} catch (err) {
_iterator.e(err);
} finally {
_iterator.f();
}
}
break;
case 'call-id':
case 'i':
message.setHeader('call-id', headerValue);
parsed = message.parseHeader('call-id');
if (parsed) {
message.call_id = headerValue;
}
break;
case 'contact':
case 'm':
parsed = Grammar.parse(headerValue, 'Contact');
if (parsed === -1) {
parsed = undefined;
} else {
var _iterator2 = _createForOfIteratorHelper(parsed),
_step2;
try {
for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
var _header = _step2.value;
message.addHeader('contact', headerValue.substring(_header.possition, _header.offset));
message.headers.Contact[message.getHeaders('contact').length - 1].parsed = _header.parsed;
}
} catch (err) {
_iterator2.e(err);
} finally {
_iterator2.f();
}
}
break;
case 'content-length':
case 'l':
message.setHeader('content-length', headerValue);
parsed = message.parseHeader('content-length');
break;
case 'content-type':
case 'c':
message.setHeader('content-type', headerValue);
parsed = message.parseHeader('content-type');
break;
case 'cseq':
message.setHeader('cseq', headerValue);
parsed = message.parseHeader('cseq');
if (parsed) {
message.cseq = parsed.value;
}
if (message instanceof SIPMessage.IncomingResponse) {
message.method = parsed.method;
}
break;
case 'max-forwards':
message.setHeader('max-forwards', headerValue);
parsed = message.parseHeader('max-forwards');
break;
case 'www-authenticate':
message.setHeader('www-authenticate', headerValue);
parsed = message.parseHeader('www-authenticate');
break;
case 'proxy-authenticate':
message.setHeader('proxy-authenticate', headerValue);
parsed = message.parseHeader('proxy-authenticate');
break;
case 'session-expires':
case 'x':
message.setHeader('session-expires', headerValue);
parsed = message.parseHeader('session-expires');
if (parsed) {
message.session_expires = parsed.expires;
message.session_expires_refresher = parsed.refresher;
}
break;
case 'refer-to':
case 'r':
message.setHeader('refer-to', headerValue);
parsed = message.parseHeader('refer-to');
if (parsed) {
message.refer_to = parsed;
}
break;
case 'replaces':
message.setHeader('replaces', headerValue);
parsed = message.parseHeader('replaces');
if (parsed) {
message.replaces = parsed;
}
break;
case 'event':
case 'o':
message.setHeader('event', headerValue);
parsed = message.parseHeader('event');
if (parsed) {
message.event = parsed;
}
break;
default:
// Do not parse this header.
message.addHeader(headerName, headerValue);
parsed = 0;
}
if (parsed === undefined) {
return {
error: "error parsing header \"".concat(headerName, "\"")
};
} else {
return true;
}
}
},{"./Grammar":7,"./Logger":9,"./SIPMessage":21}],14:[function(require,module,exports){
"use strict";
function _typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }
function _createForOfIteratorHelper(o, allowArrayLike) { var it; if (typeof Symbol === "undefined" || o[Symbol.iterator] == null) { if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e2) { throw _e2; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = o[Symbol.iterator](); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e3) { didErr = true; err = _e3; }, f: function f() { try { if (!normalCompletion && it["return"] != null) it["return"](); } finally { if (didErr) throw err; } } }; }
function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); if (superClass) _setPrototypeOf(subClass, superClass); }
function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }
function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; }
function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === "object" || typeof call === "function")) { return call; } return _assertThisInitialized(self); }
function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; }
function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); return true; } catch (e) { return false; } }
function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }
/* globals RTCPeerConnection: false, RTCSessionDescription: false */
var EventEmitter = require('events').EventEmitter;
var sdp_transform = require('sdp-transform');
var Logger = require('./Logger');
var SimpleSIP_C = require('./Constants');
var Exceptions = require('./Exceptions');
var Transactions = require('./Transactions');
var Utils = require('./Utils');
var Timers = require('./Timers');
var SIPMessage = require('./SIPMessage');
var Dialog = require('./Dialog');
var RequestSender = require('./RequestSender');
var RTCSession_DTMF = require('./RTCSession/DTMF');
var RTCSession_Info = require('./RTCSession/Info');
var RTCSession_ReferNotifier = require('./RTCSession/ReferNotifier');
var RTCSession_ReferSubscriber = require('./RTCSession/ReferSubscriber');
var URI = require('./URI');
var logger = new Logger('RTCSession');
var C = {
// RTCSession states.
STATUS_NULL: 0,
STATUS_INVITE_SENT: 1,
STATUS_1XX_RECEIVED: 2,
STATUS_INVITE_RECEIVED: 3,
STATUS_WAITING_FOR_ANSWER: 4,
STATUS_ANSWERED: 5,
STATUS_WAITING_FOR_ACK: 6,
STATUS_CANCELED: 7,
STATUS_TERMINATED: 8,
STATUS_CONFIRMED: 9
};
/**
* Local variables.
*/
var holdMediaTypes = ['audio', 'video'];
module.exports = /*#__PURE__*/function (_EventEmitter) {
_inherits(RTCSession, _EventEmitter);
var _super = _createSuper(RTCSession);
_createClass(RTCSession, null, [{
key: "C",
/**
* Expose C object.
*/
get: function get() {
return C;
}
}]);
function RTCSession(ua) {
var _this;
_classCallCheck(this, RTCSession);
logger.debug('new');
_this = _super.call(this);
_this._id = null;
_this._ua = ua;
_this._status = C.STATUS_NULL;
_this._dialog = null;
_this._earlyDialogs = {};
_this._contact = null;
_this._from_tag = null;
_this._to_tag = null; // The RTCPeerConnection instance (public attribute).
_this._connection = null; // Prevent races on serial PeerConnction operations.
_this._connectionPromiseQueue = Promise.resolve(); // Incoming/Outgoing request being currently processed.
_this._request = null; // Cancel state for initial outgoing request.
_this._is_canceled = false;
_this._cancel_reason = ''; // RTCSession confirmation flag.
_this._is_confirmed = false; // Is late SDP being negotiated.
_this._late_sdp = false; // Default rtcOfferConstraints and rtcAnswerConstrainsts (passed in connect() or answer()).
_this._rtcOfferConstraints = null;
_this._rtcAnswerConstraints = null; // Local MediaStream.
_this._localMediaStream = null;
_this._localMediaStreamLocallyGenerated = false; // Flag to indicate PeerConnection ready for new actions.
_this._rtcReady = true; // Flag to indicate ICE candidate gathering is finished even if iceGatheringState is not yet 'complete'.
_this._iceReady = false; // SIP Timers.
_this._timers = {
ackTimer: null,
expiresTimer: null,
invite2xxTimer: null,
userNoAnswerTimer: null
}; // Session info.
_this._direction = null;
_this._local_identity = null;
_this._remote_identity = null;
_this._start_time = null;
_this._end_time = null;
_this._tones = null; // Mute/Hold state.
_this._audioMuted = false;
_this._videoMuted = false;
_this._localHold = false;
_this._remoteHold = false; // Session Timers (RFC 4028).
_this._sessionTimers = {
enabled: _this._ua.configuration.session_timers,
refreshMethod: _this._ua.configuration.session_timers_refresh_method,
defaultExpires: SimpleSIP_C.SESSION_EXPIRES,
currentExpires: null,
running: false,
refresher: false,
timer: null // A setTimeout.
}; // Map of ReferSubscriber instances indexed by the REFER's CSeq number.
_this._referSubscribers = {}; // Custom session empty object for high level use.
_this._data = {};
return _this;
}
/**
* User API
*/
// Expose RTCSession constants as a property of the RTCSession instance.
_createClass(RTCSession, [{
key: "isInProgress",
value: function isInProgress() {
switch (this._status) {
case C.STATUS_NULL:
case C.STATUS_INVITE_SENT:
case C.STATUS_1XX_RECEIVED:
case C.STATUS_INVITE_RECEIVED:
case C.STATUS_WAITING_FOR_ANSWER:
return true;
default:
return false;
}
}
}, {
key: "isEstablished",
value: function isEstablished() {
switch (this._status) {
case C.STATUS_ANSWERED:
case C.STATUS_WAITING_FOR_ACK:
case C.STATUS_CONFIRMED:
return true;
default:
return false;
}
}
}, {
key: "isEnded",
value: function isEnded() {
switch (this._status) {
case C.STATUS_CANCELED:
case C.STATUS_TERMINATED:
return true;
default:
return false;
}
}
}, {
key: "isMuted",
value: function isMuted() {
return {
audio: this._audioMuted,
video: this._videoMuted
};
}
}, {
key: "isOnHold",
value: function isOnHold() {
return {
local: this._localHold,
remote: this._remoteHold
};
}
}, {
key: "connect",
value: function connect(target) {
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
var initCallback = arguments.length > 2 ? arguments[2] : undefined;
logger.debug('connect()');
var originalTarget = target;
var eventHandlers = Utils.cloneObject(options.eventHandlers);
var extraHeaders = Utils.cloneArray(options.extraHeaders);
var mediaConstraints = Utils.cloneObject(options.mediaConstraints, {
audio: true,
video: true
});
var mediaStream = options.mediaStream || null;
var pcConfig = Utils.cloneObject(options.pcConfig, {
iceServers: []
});
var rtcConstraints = options.rtcConstraints || null;
var rtcOfferConstraints = options.rtcOfferConstraints || null;
this._rtcOfferConstraints = rtcOfferConstraints;
this._rtcAnswerConstraints = options.rtcAnswerConstraints || null;
this._data = options.data || this._data; // Check target.
if (target === undefined) {
throw new TypeError('Not enough arguments');
} // Check Session Status.
if (this._status !== C.STATUS_NULL) {
throw new Exceptions.InvalidStateError(this._status);
} // Check WebRTC support.
if (!window.RTCPeerConnection) {
throw new Exceptions.NotSupportedError('WebRTC not supported');
} // Check target validity.
target = this._ua.normalizeTarget(target);
if (!target) {
throw new TypeError("Invalid target: ".concat(originalTarget));
} // Session Timers.
if (this._sessionTimers.enabled) {
if (Utils.isDecimal(options.sessionTimersExpires)) {
if (options.sessionTimersExpires >= SimpleSIP_C.MIN_SESSION_EXPIRES) {
this._sessionTimers.defaultExpires = options.sessionTimersExpires;
} else {
this._sessionTimers.defaultExpires = SimpleSIP_C.SESSION_EXPIRES;
}
}
} // Set event handlers.
for (var event in eventHandlers) {
if (Object.prototype.hasOwnProperty.call(eventHandlers, event)) {
this.on(event, eventHandlers[event]);
}
} // Session parameter initialization.
this._from_tag = Utils.newTag(); // Set anonymous property.
var anonymous = options.anonymous || false;
var requestParams = {
from_tag: this._from_tag
};
this._contact = this._ua.contact.toString({
anonymous: anonymous,
outbound: true
});
if (anonymous) {
requestParams.from_display_name = 'Anonymous';
requestParams.from_uri = new URI('sip', 'anonymous', 'anonymous.invalid');
extraHeaders.push("P-Preferred-Identity: ".concat(this._ua.configuration.uri.toString()));
extraHeaders.push('Privacy: id');
} else if (options.fromUserName) {
requestParams.from_uri = new URI('sip', options.fromUserName, this._ua.configuration.uri.host);
extraHeaders.push("P-Preferred-Identity: ".concat(this._ua.configuration.uri.toString()));
}
if (options.fromDisplayName) {
requestParams.from_display_name = options.fromDisplayName;
}
extraHeaders.push("Contact: ".concat(this._contact));
extraHeaders.push('Content-Type: application/sdp');
if (this._sessionTimers.enabled) {
extraHeaders.push("Session-Expires: ".concat(this._sessionTimers.defaultExpires).concat(this._ua.configuration.session_timers_force_refresher ? ';refresher=uac' : ''));
}
this._request = new SIPMessage.InitialOutgoingInviteRequest(target, this._ua, requestParams, extraHeaders);
this._id = this._request.call_id + this._from_tag; // Create a new RTCPeerConnection instance.
this._createRTCConnection(pcConfig, rtcConstraints); // Set internal properties.
this._direction = 'outgoing';
this._local_identity = this._request.from;
this._remote_identity = this._request.to; // User explicitly provided a newRTCSession callback for this session.
if (initCallback) {
initCallback(this);
}
this._newRTCSession('local', this._request);
this._sendInitialRequest(mediaConstraints, rtcOfferConstraints, mediaStream);
}
}, {
key: "init_incoming",
value: function init_incoming(request, initCallback) {
var _this2 = this;
logger.debug('init_incoming()');
var expires;
var contentType = request.hasHeader('Content-Type') ? request.getHeader('Content-Type').toLowerCase() : undefined; // Check body and content type.
if (request.body && contentType !== 'application/sdp') {
request.reply(415);
return;
} // Session parameter initialization.
this._status = C.STATUS_INVITE_RECEIVED;
this._from_tag = request.from_tag;
this._id = request.call_id + this._from_tag;
this._request = request;
this._contact = this._ua.contact.toString(); // Get the Expires header value if exists.
if (request.hasHeader('expires')) {
expires = request.getHeader('expires') * 1000;
}
/* Set the to_tag before
* replying a response code that will create a dialog.
*/
request.to_tag = Utils.newTag(); // An error on dialog creation will fire 'failed' event.
if (!this._createDialog(request, 'UAS', true)) {
request.reply(500, 'Missing Contact header field');
return;
}
if (request.body) {
this._late_sdp = false;
} else {
this._late_sdp = true;
}
this._status = C.STATUS_WAITING_FOR_ANSWER; // Set userNoAnswerTimer.
this._timers.userNoAnswerTimer = setTimeout(function () {
request.reply(408);
_this2._failed('local', null, SimpleSIP_C.causes.NO_ANSWER);
}, this._ua.configuration.no_answer_timeout);
/* Set expiresTimer
* RFC3261 13.3.1
*/
if (expires) {
this._timers.expiresTimer = setTimeout(function () {
if (_this2._status === C.STATUS_WAITING_FOR_ANSWER) {
request.reply(487);
_this2._failed('system', null, SimpleSIP_C.causes.EXPIRES);
}
}, expires);
} // Set internal properties.
this._direction = 'incoming';
this._local_identity = request.to;
this._remote_identity = request.from; // A init callback was specifically defined.
if (initCallback) {
initCallback(this);
} // Fire 'newRTCSession' event.
this._newRTCSession('remote', request); // The user may have rejected the call in the 'newRTCSession' event.
if (this._status === C.STATUS_TERMINATED) {
return;
} // Reply 180.
request.reply(180, null, ["Contact: ".concat(this._contact)]); // Fire 'progress' event.
// TODO: Document that 'response' field in 'progress' event is null for incoming calls.
this._progress('local', null);
}
/**
* Answer the call.
*/
}, {
key: "answer",
value: function answer() {
var _this3 = this;
var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
logger.debug('answer()');
var request = this._request;
var extraHeaders = Utils.cloneArray(options.extraHeaders);
var mediaConstraints = Utils.cloneObject(options.mediaConstraints);
var mediaStream = options.mediaStream || null;
var pcConfig = Utils.cloneObject(options.pcConfig, {
iceServers: []
});
var rtcConstraints = options.rtcConstraints || null;
var rtcAnswerConstraints = options.rtcAnswerConstraints || null;
var rtcOfferConstraints = Utils.cloneObject(options.rtcOfferConstraints);
var tracks;
var peerHasAudioLine = false;
var peerHasVideoLine = false;
var peerOffersFullAudio = false;
var peerOffersFullVideo = false;
this._rtcAnswerConstraints = rtcAnswerConstraints;
this._rtcOfferConstraints = options.rtcOfferConstraints || null;
this._data = options.data || this._data; // Check Session Direction and Status.
if (this._direction !== 'incoming') {
throw new Exceptions.NotSupportedError('"answer" not supported for outgoing RTCSession');
} // Check Session status.
if (this._status !== C.STATUS_WAITING_FOR_ANSWER) {
throw new Exceptions.InvalidStateError(this._status);
} // Session Timers.
if (this._sessionTimers.enabled) {
if (Utils.isDecimal(options.sessionTimersExpires)) {
if (options.sessionTimersExpires >= SimpleSIP_C.MIN_SESSION_EXPIRES) {
this._sessionTimers.defaultExpires = options.sessionTimersExpires;
} else {
this._sessionTimers.defaultExpires = SimpleSIP_C.SESSION_EXPIRES;
}
}
}
this._status = C.STATUS_ANSWERED; // An error on dialog creation will fire 'failed' event.
if (!this._createDialog(request, 'UAS')) {
request.reply(500, 'Error creating dialog');
return;
}
clearTimeout(this._timers.userNoAnswerTimer);
extraHeaders.unshift("Contact: ".concat(this._contact)); // Determine incoming media from incoming SDP offer (if any).
var sdp = request.parseSDP(); // Make sure sdp.media is an array, not the case if there is only one media.
if (!Array.isArray(sdp.media)) {
sdp.media = [sdp.media];
} // Go through all medias in SDP to find offered capabilities to answer with.
var _iterator = _createForOfIteratorHelper(sdp.media),
_step;
try {
for (_iterator.s(); !(_step = _iterator.n()).done;) {
var m = _step.value;
if (m.type === 'audio') {
peerHasAudioLine = true;
if (!m.direction || m.direction === 'sendrecv') {
peerOffersFullAudio = true;
}
}
if (m.type === 'video') {
peerHasVideoLine = true;
if (!m.direction || m.direction === 'sendrecv') {
peerOffersFullVideo = true;
}
}
} // Remove audio from mediaStream if suggested by mediaConstraints.
} catch (err) {
_iterator.e(err);
} finally {
_iterator.f();
}
if (mediaStream && mediaConstraints.audio === false) {
tracks = mediaStream.getAudioTracks();
var _iterator2 = _createForOfIteratorHelper(tracks),
_step2;
try {
for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
var track = _step2.value;
mediaStream.removeTrack(track);
}
} catch (err) {
_iterator2.e(err);
} finally {
_iterator2.f();
}
} // Remove video from mediaStream if suggested by mediaConstraints.
if (mediaStream && mediaConstraints.video === false) {
tracks = mediaStream.getVideoTracks();
var _iterator3 = _createForOfIteratorHelper(tracks),
_step3;
try {
for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) {
var _track = _step3.value;
mediaStream.removeTrack(_track);
}
} catch (err) {
_iterator3.e(err);
} finally {
_iterator3.f();
}
} // Set audio constraints based on incoming stream if not supplied.
if (!mediaStream && mediaConstraints.audio === undefined) {
mediaConstraints.audio = peerOffersFullAudio;
} // Set video constraints based on incoming stream if not supplied.
if (!mediaStream && mediaConstraints.video === undefined) {
mediaConstraints.video = peerOffersFullVideo;
} // Don't ask for audio if the incoming offer has no audio section.
if (!mediaStream && !peerHasAudioLine && !rtcOfferConstraints.offerToReceiveAudio) {
mediaConstraints.audio = false;
} // Don't ask for video if the incoming offer has no video section.
if (!mediaStream && !peerHasVideoLine && !rtcOfferConstraints.offerToReceiveVideo) {
mediaConstraints.video = false;
} // Create a new RTCPeerConnection instance.
// TODO: This may throw an error, should react.
this._createRTCConnection(pcConfig, rtcConstraints);
Promise.resolve() // Handle local MediaStream.
.then(function () {
// A local MediaStream is given, use it.
if (mediaStream) {
return mediaStream;
} // Audio and/or video requested, prompt getUserMedia.
else if (mediaConstraints.audio || mediaConstraints.video) {
_this3._localMediaStreamLocallyGenerated = true;
return navigator.mediaDevices.getUserMedia(mediaConstraints)["catch"](function (error) {
if (_this3._status === C.STATUS_TERMINATED) {
throw new Error('terminated');
}
request.reply(480);
_this3._failed('local', null, SimpleSIP_C.causes.USER_DENIED_MEDIA_ACCESS);
logger.warn('emit "getusermediafailed" [error:%o]', error);
_this3.emit('getusermediafailed', error);
throw new Error('getUserMedia() failed');
});
}
}) // Attach MediaStream to RTCPeerconnection.
.then(function (stream) {
if (_this3._status === C.STATUS_TERMINATED) {
throw new Error('terminated');
}
_this3._localMediaStream = stream;
if (stream) {
stream.getTracks().forEach(function (track) {
_this3._connection.addTrack(track, stream);
});
}
}) // Set remote description.
.then(function () {
if (_this3._late_sdp) {
return;
}
var e = {
originator: 'remote',
type: 'offer',
sdp: request.body
};
logger.debug('emit "sdp"');
_this3.emit('sdp', e);
var offer = new RTCSessionDescription({
type: 'offer',
sdp: e.sdp
});
_this3._connectionPromiseQueue = _this3._connectionPromiseQueue.then(function () {
return _this3._connection.setRemoteDescription(offer);
})["catch"](function (error) {
request.reply(488);
_this3._failed('system', null, SimpleSIP_C.causes.WEBRTC_ERROR);
logger.warn('emit "peerconnection:setremotedescriptionfailed" [error:%o]', error);
_this3.emit('peerconnection:setremotedescriptionfailed', error);
throw new Error('peerconnection.setRemoteDescription() failed');
});
return _this3._connectionPromiseQueue;
}) // Create local description.
.then(function () {
if (_this3._status === C.STATUS_TERMINATED) {
throw new Error('terminated');
} // TODO: Is this event already useful?
_this3._connecting(request);
if (!_this3._late_sdp) {
return _this3._createLocalDescription('answer', rtcAnswerConstraints)["catch"](function () {
request.reply(500);
throw new Error('_createLocalDescription() failed');
});
} else {
return _this3._createLocalDescription('offer', _this3._rtcOfferConstraints)["catch"](function () {
request.reply(500);
throw new Error('_createLocalDescription() failed');
});
}
}) // Send reply.
.then(function (desc) {
if (_this3._status === C.STATUS_TERMINATED) {
throw new Error('terminated');
}
_this3._handleSessionTimersInIncomingRequest(request, extraHeaders);
request.reply(200, null, extraHeaders, desc, function () {
_this3._status = C.STATUS_WAITING_FOR_ACK;
_this3._setInvite2xxTimer(request, desc);
_this3._setACKTimer();
_this3._accepted('local');
}, function () {
_this3._failed('system', null, SimpleSIP_C.causes.CONNECTION_ERROR);
});
})["catch"](function (error) {
if (_this3._status === C.STATUS_TERMINATED) {
return;
}
logger.warn(error);
});
}
/**
* Terminate the call.
*/
}, {
key: "terminate",
value: function terminate() {
var _this4 = this;
var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
logger.debug('terminate()');
var cause = options.cause || SimpleSIP_C.causes.BYE;
var extraHeaders = Utils.cloneArray(options.extraHeaders);
var body = options.body;
var cancel_reason;
var status_code = options.status_code;
var reason_phrase = options.reason_phrase; // Check Session Status.
if (this._status === C.STATUS_TERMINATED) {
throw new Exceptions.InvalidStateError(this._status);
}
switch (this._status) {
// - UAC -
case C.STATUS_NULL:
case C.STATUS_INVITE_SENT:
case C.STATUS_1XX_RECEIVED:
logger.debug('canceling session');
if (status_code && (status_code < 200 || status_code >= 700)) {
throw new TypeError("Invalid status_code: ".concat(status_code));
} else if (status_code) {
reason_phrase = reason_phrase || SimpleSIP_C.REASON_PHRASE[status_code] || '';
cancel_reason = "SIP ;cause=".concat(status_code, " ;text=\"").concat(reason_phrase, "\"");
} // Check Session Status.
if (this._status === C.STATUS_NULL || this._status === C.STATUS_INVITE_SENT) {
this._is_canceled = true;
this._cancel_reason = cancel_reason;
} else if (this._status === C.STATUS_1XX_RECEIVED) {
this._request.cancel(cancel_reason);
}
this._status = C.STATUS_CANCELED;
this._failed('local', null, SimpleSIP_C.causes.CANCELED);
break;
// - UAS -
case C.STATUS_WAITING_FOR_ANSWER:
case C.STATUS_ANSWERED:
logger.debug('rejecting session');
status_code = status_code || 480;
if (status_code < 300 || status_code >= 700) {
throw new TypeError("Invalid status_code: ".concat(status_code));
}
this._request.reply(status_code, reason_phrase, extraHeaders, body);
this._failed('local', null, SimpleSIP_C.causes.REJECTED);
break;
case C.STATUS_WAITING_FOR_ACK:
case C.STATUS_CONFIRMED:
logger.debug('terminating session');
reason_phrase = options.reason_phrase || SimpleSIP_C.REASON_PHRASE[status_code] || '';
if (status_code && (status_code < 200 || status_code >= 700)) {
throw new TypeError("Invalid status_code: ".concat(status_code));
} else if (status_code) {
extraHeaders.push("Reason: SIP ;cause=".concat(status_code, "; text=\"").concat(reason_phrase, "\""));
}
/* RFC 3261 section 15 (Terminating a session):
*
* "...the callee's UA MUST NOT send a BYE on a confirmed dialog
* until it has received an ACK for its 2xx response or until the server
* transaction times out."
*/
if (this._status === C.STATUS_WAITING_FOR_ACK && this._direction === 'incoming' && this._request.server_transaction.state !== Transactions.C.STATUS_TERMINATED) {
// Save the dialog for later restoration.
var dialog = this._dialog; // Send the BYE as soon as the ACK is received...
this.receiveRequest = function (_ref) {
var method = _ref.method;
if (method === SimpleSIP_C.ACK) {
_this4.sendRequest(SimpleSIP_C.BYE, {
extraHeaders: extraHeaders,
body: body
});
dialog.terminate();
}
}; // .., or when the INVITE transaction times out
this._request.server_transaction.on('stateChanged', function () {
if (_this4._request.server_transaction.state === Transactions.C.STATUS_TERMINATED) {
_this4.sendRequest(SimpleSIP_C.BYE, {
extraHeaders: extraHeaders,
body: body
});
dialog.terminate();
}
});
this._ended('local', null, cause); // Restore the dialog into 'this' in order to be able to send the in-dialog BYE :-).
this._dialog = dialog; // Restore the dialog into 'ua' so the ACK can reach 'this' session.
this._ua.newDialog(dialog);
} else {
this.sendRequest(SimpleSIP_C.BYE, {
extraHeaders: extraHeaders,
body: body
});
this._ended('local', null, cause);
}
}
}
}, {
key: "sendDTMF",
value: function sendDTMF(tones) {
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
logger.debug('sendDTMF() | tones: %s', tones);
var position = 0;
var duration = options.duration || null;
var interToneGap = options.interToneGap || null;
var transportType = options.transportType || SimpleSIP_C.DTMF_TRANSPORT.INFO;
if (tones === undefined) {
throw new TypeError('Not enough arguments');
} // Check Session Status.
if (this._status !== C.STATUS_CONFIRMED && this._status !== C.STATUS_WAITING_FOR_ACK && this._status !== C.STATUS_1XX_RECEIVED) {
throw new Exceptions.InvalidStateError(this._status);
} // Check Transport type.
if (transportType !== SimpleSIP_C.DTMF_TRANSPORT.INFO && transportType !== SimpleSIP_C.DTMF_TRANSPORT.RFC2833) {
throw new TypeError("invalid transportType: ".concat(transportType));
} // Convert to string.
if (typeof tones === 'number') {
tones = tones.toString();
} // Check tones.
if (!tones || typeof tones !== 'string' || !tones.match(/^[0-9A-DR#*,]+$/i)) {
throw new TypeError("Invalid tones: ".concat(tones));
} // Check duration.
if (duration && !Utils.isDecimal(duration)) {
throw new TypeError("Invalid tone duration: ".concat(duration));
} else if (!duration) {
duration = RTCSession_DTMF.C.DEFAULT_DURATION;
} else if (duration < RTCSession_DTMF.C.MIN_DURATION) {
logger.debug("\"duration\" value is lower than the minimum allowed, setting it to ".concat(RTCSession_DTMF.C.MIN_DURATION, " milliseconds"));
duration = RTCSession_DTMF.C.MIN_DURATION;
} else if (duration > RTCSession_DTMF.C.MAX_DURATION) {
logger.debug("\"duration\" value is greater than the maximum allowed, setting it to ".concat(RTCSession_DTMF.C.MAX_DURATION, " milliseconds"));
duration = RTCSession_DTMF.C.MAX_DURATION;
} else {
duration = Math.abs(duration);
}
options.duration = duration; // Check interToneGap.
if (interToneGap && !Utils.isDecimal(interToneGap)) {
throw new TypeError("Invalid interToneGap: ".concat(interToneGap));
} else if (!interToneGap) {
interToneGap = RTCSession_DTMF.C.DEFAULT_INTER_TONE_GAP;
} else if (interToneGap < RTCSession_DTMF.C.MIN_INTER_TONE_GAP) {
logger.debug("\"interToneGap\" value is lower than the minimum allowed, setting it to ".concat(RTCSession_DTMF.C.MIN_INTER_TONE_GAP, " milliseconds"));
interToneGap = RTCSession_DTMF.C.MIN_INTER_TONE_GAP;
} else {
interToneGap = Math.abs(interToneGap);
} // RFC2833. Let RTCDTMFSender enqueue the DTMFs.
if (transportType === SimpleSIP_C.DTMF_TRANSPORT.RFC2833) {
// Send DTMF in current audio RTP stream.
var sender = this._getDTMFRTPSender();
if (sender) {
// Add remaining buffered tones.
tones = sender.toneBuffer + tones; // Insert tones.
sender.insertDTMF(tones, duration, interToneGap);
}
return;
}
if (this._tones) {
// Tones are already queued, just add to the queue.
this._tones += tones;
return;
}
this._tones = tones; // Send the first tone.
_sendDTMF.call(this);
function _sendDTMF() {
var _this5 = this;
var timeout;
if (this._status === C.STATUS_TERMINATED || !this._tones || position >= this._tones.length) {
// Stop sending DTMF.
this._tones = null;
return;
}
var tone = this._tones[position];
position += 1;
if (tone === ',') {
timeout = 2000;
} else {
// Send DTMF via SIP INFO messages.
var dtmf = new RTCSession_DTMF(this);
options.eventHandlers = {
onFailed: function onFailed() {
_this5._tones = null;
}
};
dtmf.send(tone, options);
timeout = duration + interToneGap;
} // Set timeout for the next tone.
setTimeout(_sendDTMF.bind(this), timeout);
}
}
}, {
key: "sendInfo",
value: function sendInfo(contentType, body) {
var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
logger.debug('sendInfo()'); // Check Session Status.
if (this._status !== C.STATUS_CONFIRMED && this._status !== C.STATUS_WAITING_FOR_ACK && this._status !== C.STATUS_1XX_RECEIVED) {
throw new Exceptions.InvalidStateError(this._status);
}
var info = new RTCSession_Info(this);
info.send(contentType, body, options);
}
/**
* Mute
*/
}, {
key: "mute",
value: function mute() {
var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {
audio: true,
video: false
};
logger.debug('mute()');
var audioMuted = false,
videoMuted = false;
if (this._audioMuted === false && options.audio) {
audioMuted = true;
this._audioMuted = true;
this._toggleMuteAudio(true);
}
if (this._videoMuted === false && options.video) {
videoMuted = true;
this._videoMuted = true;
this._toggleMuteVideo(true);
}
if (audioMuted === true || videoMuted === true) {
this._onmute({
audio: audioMuted,
video: videoMuted
});
}
}
/**
* Unmute
*/
}, {
key: "unmute",
value: function unmute() {
var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {
audio: true,
video: true
};
logger.debug('unmute()');
var audioUnMuted = false,
videoUnMuted = false;
if (this._audioMuted === true && options.audio) {
audioUnMuted = true;
this._audioMuted = false;
if (this._localHold === false) {
this._toggleMuteAudio(false);
}
}
if (this._videoMuted === true && options.video) {
videoUnMuted = true;
this._videoMuted = false;
if (this._localHold === false) {
this._toggleMuteVideo(false);
}
}
if (audioUnMuted === true || videoUnMuted === true) {
this._onunmute({
audio: audioUnMuted,
video: videoUnMuted
});
}
}
/**
* Hold
*/
}, {
key: "hold",
value: function hold() {
var _this6 = this;
var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
var done = arguments.length > 1 ? arguments[1] : undefined;
logger.debug('hold()');
if (this._status !== C.STATUS_WAITING_FOR_ACK && this._status !== C.STATUS_CONFIRMED) {
return false;
}
if (this._localHold === true) {
return false;
}
if (!this._isReadyToReOffer()) {
return false;
}
this._localHold = true;
this._onhold('local');
var eventHandlers = {
succeeded: function succeeded() {
if (done) {
done();
}
},
failed: function failed() {
_this6.terminate({
cause: SimpleSIP_C.causes.WEBRTC_ERROR,
status_code: 500,
reason_phrase: 'Hold Failed'
});
}
};
if (options.useUpdate) {
this._sendUpdate({
sdpOffer: true,
eventHandlers: eventHandlers,
extraHeaders: options.extraHeaders
});
} else {
this._sendReinvite({
eventHandlers: eventHandlers,
extraHeaders: options.extraHeaders
});
}
return true;
}
}, {
key: "unhold",
value: function unhold() {
var _this7 = this;
var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
var done = arguments.length > 1 ? arguments[1] : undefined;
logger.debug('unhold()');
if (this._status !== C.STATUS_WAITING_FOR_ACK && this._status !== C.STATUS_CONFIRMED) {
return false;
}
if (this._localHold === false) {
return false;
}
if (!this._isReadyToReOffer()) {
return false;
}
this._localHold = false;
this._onunhold('local');
var eventHandlers = {
succeeded: function succeeded() {
if (done) {
done();
}
},
failed: function failed() {
_this7.terminate({
cause: SimpleSIP_C.causes.WEBRTC_ERROR,
status_code: 500,
reason_phrase: 'Unhold Failed'
});
}
};
if (options.useUpdate) {
this._sendUpdate({
sdpOffer: true,
eventHandlers: eventHandlers,
extraHeaders: options.extraHeaders
});
} else {
this._sendReinvite({
eventHandlers: eventHandlers,
extraHeaders: options.extraHeaders
});
}
return true;
}
}, {
key: "renegotiate",
value: function renegotiate() {
var _this8 = this;
var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
var done = arguments.length > 1 ? arguments[1] : undefined;
logger.debug('renegotiate()');
var rtcOfferConstraints = options.rtcOfferConstraints || null;
if (this._status !== C.STATUS_WAITING_FOR_ACK && this._status !== C.STATUS_CONFIRMED) {
return false;
}
if (!this._isReadyToReOffer()) {
return false;
}
var eventHandlers = {
succeeded: function succeeded() {
if (done) {
done();
}
},
failed: function failed() {
_this8.terminate({
cause: SimpleSIP_C.causes.WEBRTC_ERROR,
status_code: 500,
reason_phrase: 'Media Renegotiation Failed'
});
}
};
this._setLocalMediaStatus();
if (options.useUpdate) {
this._sendUpdate({
sdpOffer: true,
eventHandlers: eventHandlers,
rtcOfferConstraints: rtcOfferConstraints,
extraHeaders: options.extraHeaders
});
} else {
this._sendReinvite({
eventHandlers: eventHandlers,
rtcOfferConstraints: rtcOfferConstraints,
extraHeaders: options.extraHeaders
});
}
return true;
}
/**
* Refer
*/
}, {
key: "refer",
value: function refer(target, options) {
var _this9 = this;
logger.debug('refer()');
var originalTarget = target;
if (this._status !== C.STATUS_WAITING_FOR_ACK && this._status !== C.STATUS_CONFIRMED) {
return false;
} // Check target validity.
target = this._ua.normalizeTarget(target);
if (!target) {
throw new TypeError("Invalid target: ".concat(originalTarget));
}
var referSubscriber = new RTCSession_ReferSubscriber(this);
referSubscriber.sendRefer(target, options); // Store in the map.
var id = referSubscriber.id;
this._referSubscribers[id] = referSubscriber; // Listen for ending events so we can remove it from the map.
referSubscriber.on('requestFailed', function () {
delete _this9._referSubscribers[id];
});
referSubscriber.on('accepted', function () {
delete _this9._referSubscribers[id];
});
referSubscriber.on('failed', function () {
delete _this9._referSubscribers[id];
});
return referSubscriber;
}
/**
* Send a generic in-dialog Request
*/
}, {
key: "sendRequest",
value: function sendRequest(method, options) {
logger.debug('sendRequest()');
return this._dialog.sendRequest(method, options);
}
/**
* In dialog Request Reception
*/
}, {
key: "receiveRequest",
value: function receiveRequest(request) {
var _this10 = this;
logger.debug('receiveRequest()');
if (request.method === SimpleSIP_C.CANCEL) {
/* RFC3261 15 States that a UAS may have accepted an invitation while a CANCEL
* was in progress and that the UAC MAY continue with the session established by
* any 2xx response, or MAY terminate with BYE. SimpleSIP does continue with the
* established session. So the CANCEL is processed only if the session is not yet
* established.
*/
/*
* Terminate the whole session in case the user didn't accept (or yet send the answer)
* nor reject the request opening the session.
*/
if (this._status === C.STATUS_WAITING_FOR_ANSWER || this._status === C.STATUS_ANSWERED) {
this._status = C.STATUS_CANCELED;
this._request.reply(487);
this._failed('remote', request, SimpleSIP_C.causes.CANCELED);
}
} else {
// Requests arriving here are in-dialog requests.
switch (request.method) {
case SimpleSIP_C.ACK:
if (this._status !== C.STATUS_WAITING_FOR_ACK) {
return;
} // Update signaling status.
this._status = C.STATUS_CONFIRMED;
clearTimeout(this._timers.ackTimer);
clearTimeout(this._timers.invite2xxTimer);
if (this._late_sdp) {
if (!request.body) {
this.terminate({
cause: SimpleSIP_C.causes.MISSING_SDP,
status_code: 400
});
break;
}
var e = {
originator: 'remote',
type: 'answer',
sdp: request.body
};
logger.debug('emit "sdp"');
this.emit('sdp', e);
var answer = new RTCSessionDescription({
type: 'answer',
sdp: e.sdp
});
this._connectionPromiseQueue = this._connectionPromiseQueue.then(function () {
return _this10._connection.setRemoteDescription(answer);
}).then(function () {
if (!_this10._is_confirmed) {
_this10._confirmed('remote', request);
}
})["catch"](function (error) {
_this10.terminate({
cause: SimpleSIP_C.causes.BAD_MEDIA_DESCRIPTION,
status_code: 488
});
logger.warn('emit "peerconnection:setremotedescriptionfailed" [error:%o]', error);
_this10.emit('peerconnection:setremotedescriptionfailed', error);
});
} else if (!this._is_confirmed) {
this._confirmed('remote', request);
}
break;
case SimpleSIP_C.BYE:
if (this._status === C.STATUS_CONFIRMED || this._status === C.STATUS_WAITING_FOR_ACK) {
request.reply(200);
this._ended('remote', request, SimpleSIP_C.causes.BYE);
} else if (this._status === C.STATUS_INVITE_RECEIVED || this._status === C.STATUS_WAITING_FOR_ANSWER) {
request.reply(200);
this._request.reply(487, 'BYE Received');
this._ended('remote', request, SimpleSIP_C.causes.BYE);
} else {
request.reply(403, 'Wrong Status');
}
break;
case SimpleSIP_C.INVITE:
if (this._status === C.STATUS_CONFIRMED) {
if (request.hasHeader('replaces')) {
this._receiveReplaces(request);
} else {
this._receiveReinvite(request);
}
} else {
request.reply(403, 'Wrong Status');
}
break;
case SimpleSIP_C.INFO:
if (this._status === C.STATUS_1XX_RECEIVED || this._status === C.STATUS_WAITING_FOR_ANSWER || this._status === C.STATUS_ANSWERED || this._status === C.STATUS_WAITING_FOR_ACK || this._status === C.STATUS_CONFIRMED) {
var contentType = request.hasHeader('Content-Type') ? request.getHeader('Content-Type').toLowerCase() : undefined;
if (contentType && contentType.match(/^application\/dtmf-relay/i)) {
new RTCSession_DTMF(this).init_incoming(request);
} else if (contentType !== undefined) {
new RTCSession_Info(this).init_incoming(request);
} else {
request.reply(415);
}
} else {
request.reply(403, 'Wrong Status');
}
break;
case SimpleSIP_C.UPDATE:
if (this._status === C.STATUS_CONFIRMED) {
this._receiveUpdate(request);
} else {
request.reply(403, 'Wrong Status');
}
break;
case SimpleSIP_C.REFER:
if (this._status === C.STATUS_CONFIRMED) {
this._receiveRefer(request);
} else {
request.reply(403, 'Wrong Status');
}
break;
case SimpleSIP_C.NOTIFY:
if (this._status === C.STATUS_CONFIRMED) {
this._receiveNotify(request);
} else {
request.reply(403, 'Wrong Status');
}
break;
default:
request.reply(501);
}
}
}
/**
* Session Callbacks
*/
}, {
key: "onTransportError",
value: function onTransportError() {
logger.warn('onTransportError()');
if (this._status !== C.STATUS_TERMINATED) {
this.terminate({
status_code: 500,
reason_phrase: SimpleSIP_C.causes.CONNECTION_ERROR,
cause: SimpleSIP_C.causes.CONNECTION_ERROR
});
}
}
}, {
key: "onRequestTimeout",
value: function onRequestTimeout() {
logger.warn('onRequestTimeout()');
if (this._status !== C.STATUS_TERMINATED) {
this.terminate({
status_code: 408,
reason_phrase: SimpleSIP_C.causes.REQUEST_TIMEOUT,
cause: SimpleSIP_C.causes.REQUEST_TIMEOUT
});
}
}
}, {
key: "onDialogError",
value: function onDialogError() {
logger.warn('onDialogError()');
if (this._status !== C.STATUS_TERMINATED) {
this.terminate({
status_code: 500,
reason_phrase: SimpleSIP_C.causes.DIALOG_ERROR,
cause: SimpleSIP_C.causes.DIALOG_ERROR
});
}
} // Called from DTMF handler.
}, {
key: "newDTMF",
value: function newDTMF(data) {
logger.debug('newDTMF()');
this.emit('newDTMF', data);
} // Called from Info handler.
}, {
key: "newInfo",
value: function newInfo(data) {
logger.debug('newInfo()');
this.emit('newInfo', data);
}
/**
* Check if RTCSession is ready for an outgoing re-INVITE or UPDATE with SDP.
*/
}, {
key: "_isReadyToReOffer",
value: function _isReadyToReOffer() {
if (!this._rtcReady) {
logger.debug('_isReadyToReOffer() | internal WebRTC status not ready');
return false;
} // No established yet.
if (!this._dialog) {
logger.debug('_isReadyToReOffer() | session not established yet');
return false;
} // Another INVITE transaction is in progress.
if (this._dialog.uac_pending_reply === true || this._dialog.uas_pending_reply === true) {
logger.debug('_isReadyToReOffer() | there is another INVITE/UPDATE transaction in progress');
return false;
}
return true;
}
}, {
key: "_close",
value: function _close() {
logger.debug('close()'); // Close local MediaStream if it was not given by the user.
if (this._localMediaStream && this._localMediaStreamLocallyGenerated) {
logger.debug('close() | closing local MediaStream');
Utils.closeMediaStream(this._localMediaStream);
}
if (this._status === C.STATUS_TERMINATED) {
return;
}
this._status = C.STATUS_TERMINATED; // Terminate RTC.
if (this._connection) {
try {
this._connection.close();
} catch (error) {
logger.warn('close() | error closing the RTCPeerConnection: %o', error);
}
} // Terminate signaling.
// Clear SIP timers.
for (var timer in this._timers) {
if (Object.prototype.hasOwnProperty.call(this._timers, timer)) {
clearTimeout(this._timers[timer]);
}
} // Clear Session Timers.
clearTimeout(this._sessionTimers.timer); // Terminate confirmed dialog.
if (this._dialog) {
this._dialog.terminate();
delete this._dialog;
} // Terminate early dialogs.
for (var dialog in this._earlyDialogs) {
if (Object.prototype.hasOwnProperty.call(this._earlyDialogs, dialog)) {
this._earlyDialogs[dialog].terminate();
delete this._earlyDialogs[dialog];
}
} // Terminate REFER subscribers.
for (var subscriber in this._referSubscribers) {
if (Object.prototype.hasOwnProperty.call(this._referSubscribers, subscriber)) {
delete this._referSubscribers[subscriber];
}
}
this._ua.destroyRTCSession(this);
}
/**
* Private API.
*/
/**
* RFC3261 13.3.1.4
* Response retransmissions cannot be accomplished by transaction layer
* since it is destroyed when receiving the first 2xx answer
*/
}, {
key: "_setInvite2xxTimer",
value: function _setInvite2xxTimer(request, body) {
var timeout = Timers.T1;
function invite2xxRetransmission() {
if (this._status !== C.STATUS_WAITING_FOR_ACK) {
return;
}
request.reply(200, null, ["Contact: ".concat(this._contact)], body);
if (timeout < Timers.T2) {
timeout = timeout * 2;
if (timeout > Timers.T2) {
timeout = Timers.T2;
}
}
this._timers.invite2xxTimer = setTimeout(invite2xxRetransmission.bind(this), timeout);
}
this._timers.invite2xxTimer = setTimeout(invite2xxRetransmission.bind(this), timeout);
}
/**
* RFC3261 14.2
* If a UAS generates a 2xx response and never receives an ACK,
* it SHOULD generate a BYE to terminate the dialog.
*/
}, {
key: "_setACKTimer",
value: function _setACKTimer() {
var _this11 = this;
this._timers.ackTimer = setTimeout(function () {
if (_this11._status === C.STATUS_WAITING_FOR_ACK) {
logger.debug('no ACK received, terminating the session');
clearTimeout(_this11._timers.invite2xxTimer);
_this11.sendRequest(SimpleSIP_C.BYE);
_this11._ended('remote', null, SimpleSIP_C.causes.NO_ACK);
}
}, Timers.TIMER_H);
}
}, {
key: "_createRTCConnection",
value: function _createRTCConnection(pcConfig, rtcConstraints) {
var _this12 = this;
this._connection = new RTCPeerConnection(pcConfig, rtcConstraints);
this._connection.addEventListener('iceconnectionstatechange', function () {
var state = _this12._connection.iceConnectionState; // TODO: Do more with different states.
if (state === 'failed') {
_this12.terminate({
cause: SimpleSIP_C.causes.RTP_TIMEOUT,
status_code: 408,
reason_phrase: SimpleSIP_C.causes.RTP_TIMEOUT
});
}
});
logger.debug('emit "peerconnection"');
this.emit('peerconnection', {
peerconnection: this._connection
});
}
}, {
key: "_createLocalDescription",
value: function _createLocalDescription(type, constraints) {
var _this13 = this;
logger.debug('createLocalDescription()');
if (type !== 'offer' && type !== 'answer') throw new Error("createLocalDescription() | invalid type \"".concat(type, "\""));
var connection = this._connection;
this._rtcReady = false;
return Promise.resolve() // Create Offer or Answer.
.then(function () {
if (type === 'offer') {
return connection.createOffer(constraints)["catch"](function (error) {
logger.warn('emit "peerconnection:createofferfailed" [error:%o]', error);
_this13.emit('peerconnection:createofferfailed', error);
return Promise.reject(error);
});
} else {
return connection.createAnswer(constraints)["catch"](function (error) {
logger.warn('emit "peerconnection:createanswerfailed" [error:%o]', error);
_this13.emit('peerconnection:createanswerfailed', error);
return Promise.reject(error);
});
}
}) // Set local description.
.then(function (desc) {
return connection.setLocalDescription(desc)["catch"](function (error) {
_this13._rtcReady = true;
logger.warn('emit "peerconnection:setlocaldescriptionfailed" [error:%o]', error);
_this13.emit('peerconnection:setlocaldescriptionfailed', error);
return Promise.reject(error);
});
}).then(function () {
// Resolve right away if 'pc.iceGatheringState' is 'complete'.
/**
* Resolve right away if:
* - 'connection.iceGatheringState' is 'complete' and no 'iceRestart' constraint is set.
* - 'connection.iceGatheringState' is 'gathering' and 'iceReady' is true.
*/
var iceRestart = constraints && constraints.iceRestart;
if (connection.iceGatheringState === 'complete' && !iceRestart || connection.iceGatheringState === 'gathering' && _this13._iceReady) {
_this13._rtcReady = true;
var e = {
originator: 'local',
type: type,
sdp: connection.localDescription.sdp
};
logger.debug('emit "sdp"');
_this13.emit('sdp', e);
return Promise.resolve(e.sdp);
} // Add 'pc.onicencandidate' event handler to resolve on last candidate.
return new Promise(function (resolve) {
var finished = false;
var iceCandidateListener;
var iceGatheringStateListener;
_this13._iceReady = false;
var ready = function ready() {
if (finished) {
return;
}
connection.removeEventListener('icecandidate', iceCandidateListener);
connection.removeEventListener('icegatheringstatechange', iceGatheringStateListener);
finished = true;
_this13._rtcReady = true; // connection.iceGatheringState will still indicate 'gathering' and thus be blocking.
_this13._iceReady = true;
var e = {
originator: 'local',
type: type,
sdp: connection.localDescription.sdp
};
logger.debug('emit "sdp"');
_this13.emit('sdp', e);
resolve(e.sdp);
};
connection.addEventListener('icecandidate', iceCandidateListener = function iceCandidateListener(event) {
var candidate = event.candidate;
if (candidate) {
_this13.emit('icecandidate', {
candidate: candidate,
ready: ready
});
} else {
ready();
}
});
connection.addEventListener('icegatheringstatechange', iceGatheringStateListener = function iceGatheringStateListener() {
if (connection.iceGatheringState === 'complete') {
ready();
}
});
});
});
}
/**
* Dialog Management
*/
}, {
key: "_createDialog",
value: function _createDialog(message, type, early) {
var local_tag = type === 'UAS' ? message.to_tag : message.from_tag;
var remote_tag = type === 'UAS' ? message.from_tag : message.to_tag;
var id = message.call_id + local_tag + remote_tag;
var early_dialog = this._earlyDialogs[id]; // Early Dialog.
if (early) {
if (early_dialog) {
return true;
} else {
early_dialog = new Dialog(this, message, type, Dialog.C.STATUS_EARLY); // Dialog has been successfully created.
if (early_dialog.error) {
logger.debug(early_dialog.error);
this._failed('remote', message, SimpleSIP_C.causes.INTERNAL_ERROR);
return false;
} else {
this._earlyDialogs[id] = early_dialog;
return true;
}
}
} // Confirmed Dialog.
else {
this._from_tag = message.from_tag;
this._to_tag = message.to_tag; // In case the dialog is in _early_ state, update it.
if (early_dialog) {
early_dialog.update(message, type);
this._dialog = early_dialog;
delete this._earlyDialogs[id];
return true;
} // Otherwise, create a _confirmed_ dialog.
var dialog = new Dialog(this, message, type);
if (dialog.error) {
logger.debug(dialog.error);
this._failed('remote', message, SimpleSIP_C.causes.INTERNAL_ERROR);
return false;
} else {
this._dialog = dialog;
return true;
}
}
}
/**
* In dialog INVITE Reception
*/
}, {
key: "_receiveReinvite",
value: function _receiveReinvite(request) {
var _this14 = this;
logger.debug('receiveReinvite()');
var contentType = request.hasHeader('Content-Type') ? request.getHeader('Content-Type').toLowerCase() : undefined;
var data = {
request: request,
callback: undefined,
reject: reject.bind(this)
};
var rejected = false;
function reject() {
var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
rejected = true;
var status_code = options.status_code || 403;
var reason_phrase = options.reason_phrase || '';
var extraHeaders = Utils.cloneArray(options.extraHeaders);
if (this._status !== C.STATUS_CONFIRMED) {
return false;
}
if (status_code < 300 || status_code >= 700) {
throw new TypeError("Invalid status_code: ".concat(status_code));
}
request.reply(status_code, reason_phrase, extraHeaders);
} // Emit 'reinvite'.
this.emit('reinvite', data);
if (rejected) {
return;
}
this._late_sdp = false; // Request without SDP.
if (!request.body) {
this._late_sdp = true;
if (this._remoteHold) {
this._remoteHold = false;
this._onunhold('remote');
}
this._connectionPromiseQueue = this._connectionPromiseQueue.then(function () {
return _this14._createLocalDescription('offer', _this14._rtcOfferConstraints);
}).then(function (sdp) {
sendAnswer.call(_this14, sdp);
})["catch"](function () {
request.reply(500);
});
return;
} // Request with SDP.
if (contentType !== 'application/sdp') {
logger.debug('invalid Content-Type');
request.reply(415);
return;
}
this._processInDialogSdpOffer(request) // Send answer.
.then(function (desc) {
if (_this14._status === C.STATUS_TERMINATED) {
return;
}
sendAnswer.call(_this14, desc);
})["catch"](function (error) {
logger.warn(error);
});
function sendAnswer(desc) {
var _this15 = this;
var extraHeaders = ["Contact: ".concat(this._contact)];
this._handleSessionTimersInIncomingRequest(request, extraHeaders);
if (this._late_sdp) {
desc = this._mangleOffer(desc);
}
request.reply(200, null, extraHeaders, desc, function () {
_this15._status = C.STATUS_WAITING_FOR_ACK;
_this15._setInvite2xxTimer(request, desc);
_this15._setACKTimer();
}); // If callback is given execute it.
if (typeof data.callback === 'function') {
data.callback();
}
}
}
/**
* In dialog UPDATE Reception
*/
}, {
key: "_receiveUpdate",
value: function _receiveUpdate(request) {
var _this16 = this;
logger.debug('receiveUpdate()');
var contentType = request.hasHeader('Content-Type') ? request.getHeader('Content-Type').toLowerCase() : undefined;
var data = {
request: request,
callback: undefined,
reject: reject.bind(this)
};
var rejected = false;
function reject() {
var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
rejected = true;
var status_code = options.status_code || 403;
var reason_phrase = options.reason_phrase || '';
var extraHeaders = Utils.cloneArray(options.extraHeaders);
if (this._status !== C.STATUS_CONFIRMED) {
return false;
}
if (status_code < 300 || status_code >= 700) {
throw new TypeError("Invalid status_code: ".concat(status_code));
}
request.reply(status_code, reason_phrase, extraHeaders);
} // Emit 'update'.
this.emit('update', data);
if (rejected) {
return;
}
if (!request.body) {
sendAnswer.call(this, null);
return;
}
if (contentType !== 'application/sdp') {
logger.debug('invalid Content-Type');
request.reply(415);
return;
}
this._processInDialogSdpOffer(request) // Send answer.
.then(function (desc) {
if (_this16._status === C.STATUS_TERMINATED) {
return;
}
sendAnswer.call(_this16, desc);
})["catch"](function (error) {
logger.warn(error);
});
function sendAnswer(desc) {
var extraHeaders = ["Contact: ".concat(this._contact)];
this._handleSessionTimersInIncomingRequest(request, extraHeaders);
request.reply(200, null, extraHeaders, desc); // If callback is given execute it.
if (typeof data.callback === 'function') {
data.callback();
}
}
}
}, {
key: "_processInDialogSdpOffer",
value: function _processInDialogSdpOffer(request) {
var _this17 = this;
logger.debug('_processInDialogSdpOffer()');
var sdp = request.parseSDP();
var hold = false;
var _iterator4 = _createForOfIteratorHelper(sdp.media),
_step4;
try {
for (_iterator4.s(); !(_step4 = _iterator4.n()).done;) {
var m = _step4.value;
if (holdMediaTypes.indexOf(m.type) === -1) {
continue;
}
var direction = m.direction || sdp.direction || 'sendrecv';
if (direction === 'sendonly' || direction === 'inactive') {
hold = true;
} // If at least one of the streams is active don't emit 'hold'.
else {
hold = false;
break;
}
}
} catch (err) {
_iterator4.e(err);
} finally {
_iterator4.f();
}
var e = {
originator: 'remote',
type: 'offer',
sdp: request.body
};
logger.debug('emit "sdp"');
this.emit('sdp', e);
var offer = new RTCSessionDescription({
type: 'offer',
sdp: e.sdp
});
this._connectionPromiseQueue = this._connectionPromiseQueue // Set remote description.
.then(function () {
if (_this17._status === C.STATUS_TERMINATED) {
throw new Error('terminated');
}
return _this17._connection.setRemoteDescription(offer)["catch"](function (error) {
request.reply(488);
logger.warn('emit "peerconnection:setremotedescriptionfailed" [error:%o]', error);
_this17.emit('peerconnection:setremotedescriptionfailed', error);
throw error;
});
}).then(function () {
if (_this17._status === C.STATUS_TERMINATED) {
throw new Error('terminated');
}
if (_this17._remoteHold === true && hold === false) {
_this17._remoteHold = false;
_this17._onunhold('remote');
} else if (_this17._remoteHold === false && hold === true) {
_this17._remoteHold = true;
_this17._onhold('remote');
}
}) // Create local description.
.then(function () {
if (_this17._status === C.STATUS_TERMINATED) {
throw new Error('terminated');
}
return _this17._createLocalDescription('answer', _this17._rtcAnswerConstraints)["catch"](function (error) {
request.reply(500);
logger.warn('emit "peerconnection:createtelocaldescriptionfailed" [error:%o]', error);
throw error;
});
})["catch"](function (error) {
logger.warn('_processInDialogSdpOffer() failed [error: %o]', error);
});
return this._connectionPromiseQueue;
}
/**
* In dialog Refer Reception
*/
}, {
key: "_receiveRefer",
value: function _receiveRefer(request) {
var _this18 = this;
logger.debug('receiveRefer()');
if (!request.refer_to) {
logger.debug('no Refer-To header field present in REFER');
request.reply(400);
return;
}
if (request.refer_to.uri.scheme !== SimpleSIP_C.SIP) {
logger.debug('Refer-To header field points to a non-SIP URI scheme');
request.reply(416);
return;
} // Reply before the transaction timer expires.
request.reply(202);
var notifier = new RTCSession_ReferNotifier(this, request.cseq);
logger.debug('emit "refer"'); // Emit 'refer'.
this.emit('refer', {
request: request,
accept: function accept(initCallback, options) {
_accept.call(_this18, initCallback, options);
},
reject: function reject() {
_reject.call(_this18);
}
});
function _accept(initCallback) {
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
initCallback = typeof initCallback === 'function' ? initCallback : null;
if (this._status !== C.STATUS_WAITING_FOR_ACK && this._status !== C.STATUS_CONFIRMED) {
return false;
}
var session = new RTCSession(this._ua);
session.on('progress', function (_ref2) {
var response = _ref2.response;
notifier.notify(response.status_code, response.reason_phrase);
});
session.on('accepted', function (_ref3) {
var response = _ref3.response;
notifier.notify(response.status_code, response.reason_phrase);
});
session.on('_failed', function (_ref4) {
var message = _ref4.message,
cause = _ref4.cause;
if (message) {
notifier.notify(message.status_code, message.reason_phrase);
} else {
notifier.notify(487, cause);
}
}); // Consider the Replaces header present in the Refer-To URI.
if (request.refer_to.uri.hasHeader('replaces')) {
var replaces = decodeURIComponent(request.refer_to.uri.getHeader('replaces'));
options.extraHeaders = Utils.cloneArray(options.extraHeaders);
options.extraHeaders.push("Replaces: ".concat(replaces));
}
session.connect(request.refer_to.uri.toAor(), options, initCallback);
}
function _reject() {
notifier.notify(603);
}
}
/**
* In dialog Notify Reception
*/
}, {
key: "_receiveNotify",
value: function _receiveNotify(request) {
logger.debug('receiveNotify()');
if (!request.event) {
request.reply(400);
}
switch (request.event.event) {
case 'refer':
{
var id;
var referSubscriber;
if (request.event.params && request.event.params.id) {
id = request.event.params.id;
referSubscriber = this._referSubscribers[id];
} else if (Object.keys(this._referSubscribers).length === 1) {
referSubscriber = this._referSubscribers[Object.keys(this._referSubscribers)[0]];
} else {
request.reply(400, 'Missing event id parameter');
return;
}
if (!referSubscriber) {
request.reply(481, 'Subscription does not exist');
return;
}
referSubscriber.receiveNotify(request);
request.reply(200);
break;
}
default:
{
request.reply(489);
}
}
}
/**
* INVITE with Replaces Reception
*/
}, {
key: "_receiveReplaces",
value: function _receiveReplaces(request) {
var _this20 = this;
logger.debug('receiveReplaces()');
function _accept2(initCallback) {
var _this19 = this;
if (this._status !== C.STATUS_WAITING_FOR_ACK && this._status !== C.STATUS_CONFIRMED) {
return false;
}
var session = new RTCSession(this._ua); // Terminate the current session when the new one is confirmed.
session.on('confirmed', function () {
_this19.terminate();
});
session.init_incoming(request, initCallback);
}
function _reject2() {
logger.debug('Replaced INVITE rejected by the user');
request.reply(486);
} // Emit 'replace'.
this.emit('replaces', {
request: request,
accept: function accept(initCallback) {
_accept2.call(_this20, initCallback);
},
reject: function reject() {
_reject2.call(_this20);
}
});
}
/**
* Initial Request Sender
*/
}, {
key: "_sendInitialRequest",
value: function _sendInitialRequest(mediaConstraints, rtcOfferConstraints, mediaStream) {
var _this21 = this;
var request_sender = new RequestSender(this._ua, this._request, {
onRequestTimeout: function onRequestTimeout() {
_this21.onRequestTimeout();
},
onTransportError: function onTransportError() {
_this21.onTransportError();
},
// Update the request on authentication.
onAuthenticated: function onAuthenticated(request) {
_this21._request = request;
},
onReceiveResponse: function onReceiveResponse(response) {
_this21._receiveInviteResponse(response);
}
}); // This Promise is resolved within the next iteration, so the app has now
// a chance to set events such as 'peerconnection' and 'connecting'.
Promise.resolve() // Get a stream if required.
.then(function () {
// A stream is given, let the app set events such as 'peerconnection' and 'connecting'.
if (mediaStream) {
return mediaStream;
} // Request for user media access.
else if (mediaConstraints.audio || mediaConstraints.video) {
_this21._localMediaStreamLocallyGenerated = true;
return navigator.mediaDevices.getUserMedia(mediaConstraints)["catch"](function (error) {
if (_this21._status === C.STATUS_TERMINATED) {
throw new Error('terminated');
}
_this21._failed('local', null, SimpleSIP_C.causes.USER_DENIED_MEDIA_ACCESS);
logger.warn('emit "getusermediafailed" [error:%o]', error);
_this21.emit('getusermediafailed', error);
throw error;
});
}
}).then(function (stream) {
if (_this21._status === C.STATUS_TERMINATED) {
throw new Error('terminated');
}
_this21._localMediaStream = stream;
if (stream) {
stream.getTracks().forEach(function (track) {
_this21._connection.addTrack(track, stream);
});
} // TODO: should this be triggered here?
_this21._connecting(_this21._request);
return _this21._createLocalDescription('offer', rtcOfferConstraints)["catch"](function (error) {
_this21._failed('local', null, SimpleSIP_C.causes.WEBRTC_ERROR);
throw error;
});
}).then(function (desc) {
if (_this21._is_canceled || _this21._status === C.STATUS_TERMINATED) {
throw new Error('terminated');
}
_this21._request.body = desc;
_this21._status = C.STATUS_INVITE_SENT;
logger.debug('emit "sending" [request:%o]', _this21._request); // Emit 'sending' so the app can mangle the body before the request is sent.
_this21.emit('sending', {
request: _this21._request
});
request_sender.send();
})["catch"](function (error) {
if (_this21._status === C.STATUS_TERMINATED) {
return;
}
logger.warn(error);
});
}
/**
* Get DTMF RTCRtpSender.
*/
}, {
key: "_getDTMFRTPSender",
value: function _getDTMFRTPSender() {
var sender = this._connection.getSenders().find(function (rtpSender) {
return rtpSender.track && rtpSender.track.kind === 'audio';
});
if (!(sender && sender.dtmf)) {
logger.warn('sendDTMF() | no local audio track to send DTMF with');
return;
}
return sender.dtmf;
}
/**
* Reception of Response for Initial INVITE
*/
}, {
key: "_receiveInviteResponse",
value: function _receiveInviteResponse(response) {
var _this22 = this;
logger.debug('receiveInviteResponse()'); // Handle 2XX retransmissions and responses from forked requests.
if (this._dialog && response.status_code >= 200 && response.status_code <= 299) {
/*
* If it is a retransmission from the endpoint that established
* the dialog, send an ACK
*/
if (this._dialog.id.call_id === response.call_id && this._dialog.id.local_tag === response.from_tag && this._dialog.id.remote_tag === response.to_tag) {
this.sendRequest(SimpleSIP_C.ACK);
return;
} // If not, send an ACK and terminate.
else {
var dialog = new Dialog(this, response, 'UAC');
if (dialog.error !== undefined) {
logger.debug(dialog.error);
return;
}
this.sendRequest(SimpleSIP_C.ACK);
this.sendRequest(SimpleSIP_C.BYE);
return;
}
} // Proceed to cancellation if the user requested.
if (this._is_canceled) {
if (response.status_code >= 100 && response.status_code < 200) {
this._request.cancel(this._cancel_reason);
} else if (response.status_code >= 200 && response.status_code < 299) {
this._acceptAndTerminate(response);
}
return;
}
if (this._status !== C.STATUS_INVITE_SENT && this._status !== C.STATUS_1XX_RECEIVED) {
return;
}
switch (true) {
case /^100$/.test(response.status_code):
this._status = C.STATUS_1XX_RECEIVED;
break;
case /^1[0-9]{2}$/.test(response.status_code):
{
// Do nothing with 1xx responses without To tag.
if (!response.to_tag) {
logger.debug('1xx response received without to tag');
break;
} // Create Early Dialog if 1XX comes with contact.
if (response.hasHeader('contact')) {
// An error on dialog creation will fire 'failed' event.
if (!this._createDialog(response, 'UAC', true)) {
break;
}
}
this._status = C.STATUS_1XX_RECEIVED;
if (!response.body) {
this._progress('remote', response);
break;
}
var e = {
originator: 'remote',
type: 'answer',
sdp: response.body
};
logger.debug('emit "sdp"');
this.emit('sdp', e);
var answer = new RTCSessionDescription({
type: 'answer',
sdp: e.sdp
});
this._connectionPromiseQueue = this._connectionPromiseQueue.then(function () {
return _this22._connection.setRemoteDescription(answer);
}).then(function () {
return _this22._progress('remote', response);
})["catch"](function (error) {
logger.warn('emit "peerconnection:setremotedescriptionfailed" [error:%o]', error);
_this22.emit('peerconnection:setremotedescriptionfailed', error);
});
break;
}
case /^2[0-9]{2}$/.test(response.status_code):
{
this._status = C.STATUS_CONFIRMED;
if (!response.body) {
this._acceptAndTerminate(response, 400, SimpleSIP_C.causes.MISSING_SDP);
this._failed('remote', response, SimpleSIP_C.causes.BAD_MEDIA_DESCRIPTION);
break;
} // An error on dialog creation will fire 'failed' event.
if (!this._createDialog(response, 'UAC')) {
break;
}
var _e = {
originator: 'remote',
type: 'answer',
sdp: response.body
};
logger.debug('emit "sdp"');
this.emit('sdp', _e);
var _answer = new RTCSessionDescription({
type: 'answer',
sdp: _e.sdp
});
this._connectionPromiseQueue = this._connectionPromiseQueue.then(function () {
// Be ready for 200 with SDP after a 180/183 with SDP.
// We created a SDP 'answer' for it, so check the current signaling state.
if (_this22._connection.signalingState === 'stable') {
return _this22._connection.createOffer(_this22._rtcOfferConstraints).then(function (offer) {
return _this22._connection.setLocalDescription(offer);
})["catch"](function (error) {
_this22._acceptAndTerminate(response, 500, error.toString());
_this22._failed('local', response, SimpleSIP_C.causes.WEBRTC_ERROR);
});
}
}).then(function () {
_this22._connection.setRemoteDescription(_answer).then(function () {
// Handle Session Timers.
_this22._handleSessionTimersInIncomingResponse(response);
_this22._accepted('remote', response);
_this22.sendRequest(SimpleSIP_C.ACK);
_this22._confirmed('local', null);
})["catch"](function (error) {
_this22._acceptAndTerminate(response, 488, 'Not Acceptable Here');
_this22._failed('remote', response, SimpleSIP_C.causes.BAD_MEDIA_DESCRIPTION);
logger.warn('emit "peerconnection:setremotedescriptionfailed" [error:%o]', error);
_this22.emit('peerconnection:setremotedescriptionfailed', error);
});
});
break;
}
default:
{
var cause = Utils.sipErrorCause(response.status_code);
this._failed('remote', response, cause);
}
}
}
/**
* Send Re-INVITE
*/
}, {
key: "_sendReinvite",
value: function _sendReinvite() {
var _this23 = this;
var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
logger.debug('sendReinvite()');
var extraHeaders = Utils.cloneArray(options.extraHeaders);
var eventHandlers = Utils.cloneObject(options.eventHandlers);
var rtcOfferConstraints = options.rtcOfferConstraints || this._rtcOfferConstraints || null;
var succeeded = false;
extraHeaders.push("Contact: ".concat(this._contact));
extraHeaders.push('Content-Type: application/sdp'); // Session Timers.
if (this._sessionTimers.running) {
extraHeaders.push("Session-Expires: ".concat(this._sessionTimers.currentExpires, ";refresher=").concat(this._sessionTimers.refresher ? 'uac' : 'uas'));
}
this._connectionPromiseQueue = this._connectionPromiseQueue.then(function () {
return _this23._createLocalDescription('offer', rtcOfferConstraints);
}).then(function (sdp) {
sdp = _this23._mangleOffer(sdp);
var e = {
originator: 'local',
type: 'offer',
sdp: sdp
};
logger.debug('emit "sdp"');
_this23.emit('sdp', e);
_this23.sendRequest(SimpleSIP_C.INVITE, {
extraHeaders: extraHeaders,
body: sdp,
eventHandlers: {
onSuccessResponse: function onSuccessResponse(response) {
onSucceeded.call(_this23, response);
succeeded = true;
},
onErrorResponse: function onErrorResponse(response) {
onFailed.call(_this23, response);
},
onTransportError: function onTransportError() {
_this23.onTransportError(); // Do nothing because session ends.
},
onRequestTimeout: function onRequestTimeout() {
_this23.onRequestTimeout(); // Do nothing because session ends.
},
onDialogError: function onDialogError() {
_this23.onDialogError(); // Do nothing because session ends.
}
}
});
})["catch"](function () {
onFailed();
});
function onSucceeded(response) {
var _this24 = this;
if (this._status === C.STATUS_TERMINATED) {
return;
}
this.sendRequest(SimpleSIP_C.ACK); // If it is a 2XX retransmission exit now.
if (succeeded) {
return;
} // Handle Session Timers.
this._handleSessionTimersInIncomingResponse(response); // Must have SDP answer.
if (!response.body) {
onFailed.call(this);
return;
} else if (!response.hasHeader('Content-Type') || response.getHeader('Content-Type').toLowerCase() !== 'application/sdp') {
onFailed.call(this);
return;
}
var e = {
originator: 'remote',
type: 'answer',
sdp: response.body
};
logger.debug('emit "sdp"');
this.emit('sdp', e);
var answer = new RTCSessionDescription({
type: 'answer',
sdp: e.sdp
});
this._connectionPromiseQueue = this._connectionPromiseQueue.then(function () {
return _this24._connection.setRemoteDescription(answer);
}).then(function () {
if (eventHandlers.succeeded) {
eventHandlers.succeeded(response);
}
})["catch"](function (error) {
onFailed.call(_this24);
logger.warn('emit "peerconnection:setremotedescriptionfailed" [error:%o]', error);
_this24.emit('peerconnection:setremotedescriptionfailed', error);
});
}
function onFailed(response) {
if (eventHandlers.failed) {
eventHandlers.failed(response);
}
}
}
/**
* Send UPDATE
*/
}, {
key: "_sendUpdate",
value: function _sendUpdate() {
var _this25 = this;
var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
logger.debug('sendUpdate()');
var extraHeaders = Utils.cloneArray(options.extraHeaders);
var eventHandlers = Utils.cloneObject(options.eventHandlers);
var rtcOfferConstraints = options.rtcOfferConstraints || this._rtcOfferConstraints || null;
var sdpOffer = options.sdpOffer || false;
var succeeded = false;
extraHeaders.push("Contact: ".concat(this._contact)); // Session Timers.
if (this._sessionTimers.running) {
extraHeaders.push("Session-Expires: ".concat(this._sessionTimers.currentExpires, ";refresher=").concat(this._sessionTimers.refresher ? 'uac' : 'uas'));
}
if (sdpOffer) {
extraHeaders.push('Content-Type: application/sdp');
this._connectionPromiseQueue = this._connectionPromiseQueue.then(function () {
return _this25._createLocalDescription('offer', rtcOfferConstraints);
}).then(function (sdp) {
sdp = _this25._mangleOffer(sdp);
var e = {
originator: 'local',
type: 'offer',
sdp: sdp
};
logger.debug('emit "sdp"');
_this25.emit('sdp', e);
_this25.sendRequest(SimpleSIP_C.UPDATE, {
extraHeaders: extraHeaders,
body: sdp,
eventHandlers: {
onSuccessResponse: function onSuccessResponse(response) {
onSucceeded.call(_this25, response);
succeeded = true;
},
onErrorResponse: function onErrorResponse(response) {
onFailed.call(_this25, response);
},
onTransportError: function onTransportError() {
_this25.onTransportError(); // Do nothing because session ends.
},
onRequestTimeout: function onRequestTimeout() {
_this25.onRequestTimeout(); // Do nothing because session ends.
},
onDialogError: function onDialogError() {
_this25.onDialogError(); // Do nothing because session ends.
}
}
});
})["catch"](function () {
onFailed.call(_this25);
});
} // No SDP.
else {
this.sendRequest(SimpleSIP_C.UPDATE, {
extraHeaders: extraHeaders,
eventHandlers: {
onSuccessResponse: function onSuccessResponse(response) {
onSucceeded.call(_this25, response);
},
onErrorResponse: function onErrorResponse(response) {
onFailed.call(_this25, response);
},
onTransportError: function onTransportError() {
_this25.onTransportError(); // Do nothing because session ends.
},
onRequestTimeout: function onRequestTimeout() {
_this25.onRequestTimeout(); // Do nothing because session ends.
},
onDialogError: function onDialogError() {
_this25.onDialogError(); // Do nothing because session ends.
}
}
});
}
function onSucceeded(response) {
var _this26 = this;
if (this._status === C.STATUS_TERMINATED) {
return;
} // If it is a 2XX retransmission exit now.
if (succeeded) {
return;
} // Handle Session Timers.
this._handleSessionTimersInIncomingResponse(response); // Must have SDP answer.
if (sdpOffer) {
if (!response.body) {
onFailed.call(this);
return;
} else if (!response.hasHeader('Content-Type') || response.getHeader('Content-Type').toLowerCase() !== 'application/sdp') {
onFailed.call(this);
return;
}
var e = {
originator: 'remote',
type: 'answer',
sdp: response.body
};
logger.debug('emit "sdp"');
this.emit('sdp', e);
var answer = new RTCSessionDescription({
type: 'answer',
sdp: e.sdp
});
this._connectionPromiseQueue = this._connectionPromiseQueue.then(function () {
return _this26._connection.setRemoteDescription(answer);
}).then(function () {
if (eventHandlers.succeeded) {
eventHandlers.succeeded(response);
}
})["catch"](function (error) {
onFailed.call(_this26);
logger.warn('emit "peerconnection:setremotedescriptionfailed" [error:%o]', error);
_this26.emit('peerconnection:setremotedescriptionfailed', error);
});
} // No SDP answer.
else if (eventHandlers.succeeded) {
eventHandlers.succeeded(response);
}
}
function onFailed(response) {
if (eventHandlers.failed) {
eventHandlers.failed(response);
}
}
}
}, {
key: "_acceptAndTerminate",
value: function _acceptAndTerminate(response, status_code, reason_phrase) {
logger.debug('acceptAndTerminate()');
var extraHeaders = [];
if (status_code) {
reason_phrase = reason_phrase || SimpleSIP_C.REASON_PHRASE[status_code] || '';
extraHeaders.push("Reason: SIP ;cause=".concat(status_code, "; text=\"").concat(reason_phrase, "\""));
} // An error on dialog creation will fire 'failed' event.
if (this._dialog || this._createDialog(response, 'UAC')) {
this.sendRequest(SimpleSIP_C.ACK);
this.sendRequest(SimpleSIP_C.BYE, {
extraHeaders: extraHeaders
});
} // Update session status.
this._status = C.STATUS_TERMINATED;
}
/**
* Correctly set the SDP direction attributes if the call is on local hold
*/
}, {
key: "_mangleOffer",
value: function _mangleOffer(sdp) {
if (!this._localHold && !this._remoteHold) {
return sdp;
}
sdp = sdp_transform.parse(sdp); // Local hold.
if (this._localHold && !this._remoteHold) {
logger.debug('mangleOffer() | me on hold, mangling offer');
var _iterator5 = _createForOfIteratorHelper(sdp.media),
_step5;
try {
for (_iterator5.s(); !(_step5 = _iterator5.n()).done;) {
var m = _step5.value;
if (holdMediaTypes.indexOf(m.type) === -1) {
continue;
}
if (!m.direction) {
m.direction = 'sendonly';
} else if (m.direction === 'sendrecv') {
m.direction = 'sendonly';
} else if (m.direction === 'recvonly') {
m.direction = 'inactive';
}
}
} catch (err) {
_iterator5.e(err);
} finally {
_iterator5.f();
}
} // Local and remote hold.
else if (this._localHold && this._remoteHold) {
logger.debug('mangleOffer() | both on hold, mangling offer');
var _iterator6 = _createForOfIteratorHelper(sdp.media),
_step6;
try {
for (_iterator6.s(); !(_step6 = _iterator6.n()).done;) {
var _m = _step6.value;
if (holdMediaTypes.indexOf(_m.type) === -1) {
continue;
}
_m.direction = 'inactive';
}
} catch (err) {
_iterator6.e(err);
} finally {
_iterator6.f();
}
} // Remote hold.
else if (this._remoteHold) {
logger.debug('mangleOffer() | remote on hold, mangling offer');
var _iterator7 = _createForOfIteratorHelper(sdp.media),
_step7;
try {
for (_iterator7.s(); !(_step7 = _iterator7.n()).done;) {
var _m2 = _step7.value;
if (holdMediaTypes.indexOf(_m2.type) === -1) {
continue;
}
if (!_m2.direction) {
_m2.direction = 'recvonly';
} else if (_m2.direction === 'sendrecv') {
_m2.direction = 'recvonly';
} else if (_m2.direction === 'recvonly') {
_m2.direction = 'inactive';
}
}
} catch (err) {
_iterator7.e(err);
} finally {
_iterator7.f();
}
}
return sdp_transform.write(sdp);
}
}, {
key: "_setLocalMediaStatus",
value: function _setLocalMediaStatus() {
var enableAudio = true,
enableVideo = true;
if (this._localHold || this._remoteHold) {
enableAudio = false;
enableVideo = false;
}
if (this._audioMuted) {
enableAudio = false;
}
if (this._videoMuted) {
enableVideo = false;
}
this._toggleMuteAudio(!enableAudio);
this._toggleMuteVideo(!enableVideo);
}
/**
* Handle SessionTimers for an incoming INVITE or UPDATE.
* @param {IncomingRequest} request
* @param {Array} responseExtraHeaders Extra headers for the 200 response.
*/
}, {
key: "_handleSessionTimersInIncomingRequest",
value: function _handleSessionTimersInIncomingRequest(request, responseExtraHeaders) {
if (!this._sessionTimers.enabled) {
return;
}
var session_expires_refresher;
if (request.session_expires && request.session_expires >= SimpleSIP_C.MIN_SESSION_EXPIRES) {
this._sessionTimers.currentExpires = request.session_expires;
session_expires_refresher = request.session_expires_refresher || 'uas';
} else {
this._sessionTimers.currentExpires = this._sessionTimers.defaultExpires;
session_expires_refresher = 'uas';
}
responseExtraHeaders.push("Session-Expires: ".concat(this._sessionTimers.currentExpires, ";refresher=").concat(session_expires_refresher));
this._sessionTimers.refresher = session_expires_refresher === 'uas';
this._runSessionTimer();
}
/**
* Handle SessionTimers for an incoming response to INVITE or UPDATE.
* @param {IncomingResponse} response
*/
}, {
key: "_handleSessionTimersInIncomingResponse",
value: function _handleSessionTimersInIncomingResponse(response) {
if (!this._sessionTimers.enabled) {
return;
}
var session_expires_refresher;
if (response.session_expires && response.session_expires >= SimpleSIP_C.MIN_SESSION_EXPIRES) {
this._sessionTimers.currentExpires = response.session_expires;
session_expires_refresher = response.session_expires_refresher || 'uac';
} else {
this._sessionTimers.currentExpires = this._sessionTimers.defaultExpires;
session_expires_refresher = 'uac';
}
this._sessionTimers.refresher = session_expires_refresher === 'uac';
this._runSessionTimer();
}
}, {
key: "_runSessionTimer",
value: function _runSessionTimer() {
var _this27 = this;
var expires = this._sessionTimers.currentExpires;
this._sessionTimers.running = true;
clearTimeout(this._sessionTimers.timer); // I'm the refresher.
if (this._sessionTimers.refresher) {
this._sessionTimers.timer = setTimeout(function () {
if (_this27._status === C.STATUS_TERMINATED) {
return;
}
if (!_this27._isReadyToReOffer()) {
return;
}
logger.debug('runSessionTimer() | sending session refresh request');
if (_this27._sessionTimers.refreshMethod === SimpleSIP_C.UPDATE) {
_this27._sendUpdate();
} else {
_this27._sendReinvite();
}
}, expires * 500); // Half the given interval (as the RFC states).
} // I'm not the refresher.
else {
this._sessionTimers.timer = setTimeout(function () {
if (_this27._status === C.STATUS_TERMINATED) {
return;
}
logger.warn('runSessionTimer() | timer expired, terminating the session');
_this27.terminate({
cause: SimpleSIP_C.causes.REQUEST_TIMEOUT,
status_code: 408,
reason_phrase: 'Session Timer Expired'
});
}, expires * 1100);
}
}
}, {
key: "_toggleMuteAudio",
value: function _toggleMuteAudio(mute) {
var senders = this._connection.getSenders().filter(function (sender) {
return sender.track && sender.track.kind === 'audio';
});
var _iterator8 = _createForOfIteratorHelper(senders),
_step8;
try {
for (_iterator8.s(); !(_step8 = _iterator8.n()).done;) {
var sender = _step8.value;
sender.track.enabled = !mute;
}
} catch (err) {
_iterator8.e(err);
} finally {
_iterator8.f();
}
}
}, {
key: "_toggleMuteVideo",
value: function _toggleMuteVideo(mute) {
var senders = this._connection.getSenders().filter(function (sender) {
return sender.track && sender.track.kind === 'video';
});
var _iterator9 = _createForOfIteratorHelper(senders),
_step9;
try {
for (_iterator9.s(); !(_step9 = _iterator9.n()).done;) {
var sender = _step9.value;
sender.track.enabled = !mute;
}
} catch (err) {
_iterator9.e(err);
} finally {
_iterator9.f();
}
}
}, {
key: "_newRTCSession",
value: function _newRTCSession(originator, request) {
logger.debug('newRTCSession()');
this._ua.newRTCSession(this, {
originator: originator,
session: this,
request: request
});
}
}, {
key: "_connecting",
value: function _connecting(request) {
logger.debug('session connecting');
logger.debug('emit "connecting"');
this.emit('connecting', {
request: request
});
}
}, {
key: "_progress",
value: function _progress(originator, response) {
logger.debug('session progress');
logger.debug('emit "progress"');
this.emit('progress', {
originator: originator,
response: response || null
});
}
}, {
key: "_accepted",
value: function _accepted(originator, message) {
logger.debug('session accepted');
this._start_time = new Date();
logger.debug('emit "accepted"');
this.emit('accepted', {
originator: originator,
response: message || null
});
}
}, {
key: "_confirmed",
value: function _confirmed(originator, ack) {
logger.debug('session confirmed');
this._is_confirmed = true;
logger.debug('emit "confirmed"');
this.emit('confirmed', {
originator: originator,
ack: ack || null
});
}
}, {
key: "_ended",
value: function _ended(originator, message, cause) {
logger.debug('session ended');
this._end_time = new Date();
this._close();
logger.debug('emit "ended"');
this.emit('ended', {
originator: originator,
message: message || null,
cause: cause
});
}
}, {
key: "_failed",
value: function _failed(originator, message, cause) {
logger.debug('session failed'); // Emit private '_failed' event first.
logger.debug('emit "_failed"');
this.emit('_failed', {
originator: originator,
message: message || null,
cause: cause
});
this._close();
logger.debug('emit "failed"');
this.emit('failed', {
originator: originator,
message: message || null,
cause: cause
});
}
}, {
key: "_onhold",
value: function _onhold(originator) {
logger.debug('session onhold');
this._setLocalMediaStatus();
logger.debug('emit "hold"');
this.emit('hold', {
originator: originator
});
}
}, {
key: "_onunhold",
value: function _onunhold(originator) {
logger.debug('session onunhold');
this._setLocalMediaStatus();
logger.debug('emit "unhold"');
this.emit('unhold', {
originator: originator
});
}
}, {
key: "_onmute",
value: function _onmute(_ref5) {
var audio = _ref5.audio,
video = _ref5.video;
logger.debug('session onmute');
this._setLocalMediaStatus();
logger.debug('emit "muted"');
this.emit('muted', {
audio: audio,
video: video
});
}
}, {
key: "_onunmute",
value: function _onunmute(_ref6) {
var audio = _ref6.audio,
video = _ref6.video;
logger.debug('session onunmute');
this._setLocalMediaStatus();
logger.debug('emit "unmuted"');
this.emit('unmuted', {
audio: audio,
video: video
});
}
}, {
key: "C",
get: function get() {
return C;
} // Expose session failed/ended causes as a property of the RTCSession instance.
}, {
key: "causes",
get: function get() {
return SimpleSIP_C.causes;
}
}, {
key: "id",
get: function get() {
return this._id;
}
}, {
key: "connection",
get: function get() {
return this._connection;
}
}, {
key: "contact",
get: function get() {
return this._contact;
}
}, {
key: "direction",
get: function get() {
return this._direction;
}
}, {
key: "local_identity",
get: function get() {
return this._local_identity;
}
}, {
key: "remote_identity",
get: function get() {
return this._remote_identity;
}
}, {
key: "start_time",
get: function get() {
return this._start_time;
}
}, {
key: "end_time",
get: function get() {
return this._end_time;
}
}, {
key: "data",
get: function get() {
return this._data;
},
set: function set(_data) {
this._data = _data;
}
}, {
key: "status",
get: function get() {
return this._status;
}
}]);
return RTCSession;
}(EventEmitter);
},{"./Constants":2,"./Dialog":3,"./Exceptions":6,"./Logger":9,"./RTCSession/DTMF":15,"./RTCSession/Info":16,"./RTCSession/ReferNotifier":17,"./RTCSession/ReferSubscriber":18,"./RequestSender":20,"./SIPMessage":21,"./Timers":23,"./Transactions":24,"./URI":27,"./Utils":28,"events":31,"sdp-transform":37}],15:[function(require,module,exports){
"use strict";
function _typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); if (superClass) _setPrototypeOf(subClass, superClass); }
function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }
function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; }
function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === "object" || typeof call === "function")) { return call; } return _assertThisInitialized(self); }
function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; }
function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); return true; } catch (e) { return false; } }
function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }
var EventEmitter = require('events').EventEmitter;
var Logger = require('../Logger');
var SimpleSIP_C = require('../Constants');
var Exceptions = require('../Exceptions');
var Utils = require('../Utils');
var logger = new Logger('RTCSession:DTMF');
var C = {
MIN_DURATION: 70,
MAX_DURATION: 6000,
DEFAULT_DURATION: 100,
MIN_INTER_TONE_GAP: 50,
DEFAULT_INTER_TONE_GAP: 500
};
module.exports = /*#__PURE__*/function (_EventEmitter) {
_inherits(DTMF, _EventEmitter);
var _super = _createSuper(DTMF);
function DTMF(session) {
var _this;
_classCallCheck(this, DTMF);
_this = _super.call(this);
_this._session = session;
_this._direction = null;
_this._tone = null;
_this._duration = null;
_this._request = null;
return _this;
}
_createClass(DTMF, [{
key: "send",
value: function send(tone) {
var _this2 = this;
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
if (tone === undefined) {
throw new TypeError('Not enough arguments');
}
this._direction = 'outgoing'; // Check RTCSession Status.
if (this._session.status !== this._session.C.STATUS_CONFIRMED && this._session.status !== this._session.C.STATUS_WAITING_FOR_ACK) {
throw new Exceptions.InvalidStateError(this._session.status);
}
var extraHeaders = Utils.cloneArray(options.extraHeaders);
this.eventHandlers = Utils.cloneObject(options.eventHandlers); // Check tone type.
if (typeof tone === 'string') {
tone = tone.toUpperCase();
} else if (typeof tone === 'number') {
tone = tone.toString();
} else {
throw new TypeError("Invalid tone: ".concat(tone));
} // Check tone value.
if (!tone.match(/^[0-9A-DR#*]$/)) {
throw new TypeError("Invalid tone: ".concat(tone));
} else {
this._tone = tone;
} // Duration is checked/corrected in RTCSession.
this._duration = options.duration;
extraHeaders.push('Content-Type: application/dtmf-relay');
var body = "Signal=".concat(this._tone, "\r\n");
body += "Duration=".concat(this._duration);
this._session.newDTMF({
originator: 'local',
dtmf: this,
request: this._request
});
this._session.sendRequest(SimpleSIP_C.INFO, {
extraHeaders: extraHeaders,
eventHandlers: {
onSuccessResponse: function onSuccessResponse(response) {
_this2.emit('succeeded', {
originator: 'remote',
response: response
});
},
onErrorResponse: function onErrorResponse(response) {
if (_this2.eventHandlers.onFailed) {
_this2.eventHandlers.onFailed();
}
_this2.emit('failed', {
originator: 'remote',
response: response
});
},
onRequestTimeout: function onRequestTimeout() {
_this2._session.onRequestTimeout();
},
onTransportError: function onTransportError() {
_this2._session.onTransportError();
},
onDialogError: function onDialogError() {
_this2._session.onDialogError();
}
},
body: body
});
}
}, {
key: "init_incoming",
value: function init_incoming(request) {
var reg_tone = /^(Signal\s*?=\s*?)([0-9A-D#*]{1})(\s)?.*/;
var reg_duration = /^(Duration\s?=\s?)([0-9]{1,4})(\s)?.*/;
this._direction = 'incoming';
this._request = request;
request.reply(200);
if (request.body) {
var body = request.body.split('\n');
if (body.length >= 1) {
if (reg_tone.test(body[0])) {
this._tone = body[0].replace(reg_tone, '$2');
}
}
if (body.length >= 2) {
if (reg_duration.test(body[1])) {
this._duration = parseInt(body[1].replace(reg_duration, '$2'), 10);
}
}
}
if (!this._duration) {
this._duration = C.DEFAULT_DURATION;
}
if (!this._tone) {
logger.debug('invalid INFO DTMF received, discarded');
} else {
this._session.newDTMF({
originator: 'remote',
dtmf: this,
request: request
});
}
}
}, {
key: "tone",
get: function get() {
return this._tone;
}
}, {
key: "duration",
get: function get() {
return this._duration;
}
}]);
return DTMF;
}(EventEmitter);
/**
* Expose C object.
*/
module.exports.C = C;
},{"../Constants":2,"../Exceptions":6,"../Logger":9,"../Utils":28,"events":31}],16:[function(require,module,exports){
"use strict";
function _typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); if (superClass) _setPrototypeOf(subClass, superClass); }
function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }
function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; }
function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === "object" || typeof call === "function")) { return call; } return _assertThisInitialized(self); }
function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; }
function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); return true; } catch (e) { return false; } }
function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }
var EventEmitter = require('events').EventEmitter;
var SimpleSIP_C = require('../Constants');
var Exceptions = require('../Exceptions');
var Utils = require('../Utils');
module.exports = /*#__PURE__*/function (_EventEmitter) {
_inherits(Info, _EventEmitter);
var _super = _createSuper(Info);
function Info(session) {
var _this;
_classCallCheck(this, Info);
_this = _super.call(this);
_this._session = session;
_this._direction = null;
_this._contentType = null;
_this._body = null;
return _this;
}
_createClass(Info, [{
key: "send",
value: function send(contentType, body) {
var _this2 = this;
var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
this._direction = 'outgoing';
if (contentType === undefined) {
throw new TypeError('Not enough arguments');
} // Check RTCSession Status.
if (this._session.status !== this._session.C.STATUS_CONFIRMED && this._session.status !== this._session.C.STATUS_WAITING_FOR_ACK) {
throw new Exceptions.InvalidStateError(this._session.status);
}
this._contentType = contentType;
this._body = body;
var extraHeaders = Utils.cloneArray(options.extraHeaders);
extraHeaders.push("Content-Type: ".concat(contentType));
this._session.newInfo({
originator: 'local',
info: this,
request: this.request
});
this._session.sendRequest(SimpleSIP_C.INFO, {
extraHeaders: extraHeaders,
eventHandlers: {
onSuccessResponse: function onSuccessResponse(response) {
_this2.emit('succeeded', {
originator: 'remote',
response: response
});
},
onErrorResponse: function onErrorResponse(response) {
_this2.emit('failed', {
originator: 'remote',
response: response
});
},
onTransportError: function onTransportError() {
_this2._session.onTransportError();
},
onRequestTimeout: function onRequestTimeout() {
_this2._session.onRequestTimeout();
},
onDialogError: function onDialogError() {
_this2._session.onDialogError();
}
},
body: body
});
}
}, {
key: "init_incoming",
value: function init_incoming(request) {
this._direction = 'incoming';
this.request = request;
request.reply(200);
this._contentType = request.hasHeader('Content-Type') ? request.getHeader('Content-Type').toLowerCase() : undefined;
this._body = request.body;
this._session.newInfo({
originator: 'remote',
info: this,
request: request
});
}
}, {
key: "contentType",
get: function get() {
return this._contentType;
}
}, {
key: "body",
get: function get() {
return this._body;
}
}]);
return Info;
}(EventEmitter);
},{"../Constants":2,"../Exceptions":6,"../Utils":28,"events":31}],17:[function(require,module,exports){
"use strict";
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }
var Logger = require('../Logger');
var SimpleSIP_C = require('../Constants');
var logger = new Logger('RTCSession:ReferNotifier');
var C = {
event_type: 'refer',
body_type: 'message/sipfrag;version=2.0',
expires: 300
};
module.exports = /*#__PURE__*/function () {
function ReferNotifier(session, id, expires) {
_classCallCheck(this, ReferNotifier);
this._session = session;
this._id = id;
this._expires = expires || C.expires;
this._active = true; // The creation of a Notifier results in an immediate NOTIFY.
this.notify(100);
}
_createClass(ReferNotifier, [{
key: "notify",
value: function notify(code, reason) {
logger.debug('notify()');
if (this._active === false) {
return;
}
reason = reason || SimpleSIP_C.REASON_PHRASE[code] || '';
var state;
if (code >= 200) {
state = 'terminated;reason=noresource';
} else {
state = "active;expires=".concat(this._expires);
} // Put this in a try/catch block.
this._session.sendRequest(SimpleSIP_C.NOTIFY, {
extraHeaders: ["Event: ".concat(C.event_type, ";id=").concat(this._id), "Subscription-State: ".concat(state), "Content-Type: ".concat(C.body_type)],
body: "SIP/2.0 ".concat(code, " ").concat(reason),
eventHandlers: {
// If a negative response is received, subscription is canceled.
onErrorResponse: function onErrorResponse() {
this._active = false;
}
}
});
}
}]);
return ReferNotifier;
}();
},{"../Constants":2,"../Logger":9}],18:[function(require,module,exports){
"use strict";
function _typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); if (superClass) _setPrototypeOf(subClass, superClass); }
function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }
function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; }
function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === "object" || typeof call === "function")) { return call; } return _assertThisInitialized(self); }
function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; }
function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); return true; } catch (e) { return false; } }
function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }
var EventEmitter = require('events').EventEmitter;
var Logger = require('../Logger');
var SimpleSIP_C = require('../Constants');
var Grammar = require('../Grammar');
var Utils = require('../Utils');
var logger = new Logger('RTCSession:ReferSubscriber');
module.exports = /*#__PURE__*/function (_EventEmitter) {
_inherits(ReferSubscriber, _EventEmitter);
var _super = _createSuper(ReferSubscriber);
function ReferSubscriber(session) {
var _this;
_classCallCheck(this, ReferSubscriber);
_this = _super.call(this);
_this._id = null;
_this._session = session;
return _this;
}
_createClass(ReferSubscriber, [{
key: "sendRefer",
value: function sendRefer(target) {
var _this2 = this;
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
logger.debug('sendRefer()');
var extraHeaders = Utils.cloneArray(options.extraHeaders);
var eventHandlers = Utils.cloneObject(options.eventHandlers); // Set event handlers.
for (var event in eventHandlers) {
if (Object.prototype.hasOwnProperty.call(eventHandlers, event)) {
this.on(event, eventHandlers[event]);
}
} // Replaces URI header field.
var replaces = null;
if (options.replaces) {
replaces = options.replaces._request.call_id;
replaces += ";to-tag=".concat(options.replaces._to_tag);
replaces += ";from-tag=".concat(options.replaces._from_tag);
replaces = encodeURIComponent(replaces);
} // Refer-To header field.
var referTo = "Refer-To: <".concat(target).concat(replaces ? "?Replaces=".concat(replaces) : '', ">");
extraHeaders.push(referTo); // Referred-By header field (if not already present).
if (!extraHeaders.some(function (header) {
return header.toLowerCase().startsWith('referred-by:');
})) {
var referredBy = "Referred-By: <".concat(this._session._ua._configuration.uri._scheme, ":").concat(this._session._ua._configuration.uri._user, "@").concat(this._session._ua._configuration.uri._host, ">");
extraHeaders.push(referredBy);
}
extraHeaders.push("Contact: ".concat(this._session.contact));
var request = this._session.sendRequest(SimpleSIP_C.REFER, {
extraHeaders: extraHeaders,
eventHandlers: {
onSuccessResponse: function onSuccessResponse(response) {
_this2._requestSucceeded(response);
},
onErrorResponse: function onErrorResponse(response) {
_this2._requestFailed(response, SimpleSIP_C.causes.REJECTED);
},
onTransportError: function onTransportError() {
_this2._requestFailed(null, SimpleSIP_C.causes.CONNECTION_ERROR);
},
onRequestTimeout: function onRequestTimeout() {
_this2._requestFailed(null, SimpleSIP_C.causes.REQUEST_TIMEOUT);
},
onDialogError: function onDialogError() {
_this2._requestFailed(null, SimpleSIP_C.causes.DIALOG_ERROR);
}
}
});
this._id = request.cseq;
}
}, {
key: "receiveNotify",
value: function receiveNotify(request) {
logger.debug('receiveNotify()');
if (!request.body) {
return;
}
var status_line = Grammar.parse(request.body.trim().split('\r\n', 1)[0], 'Status_Line');
if (status_line === -1) {
logger.debug("receiveNotify() | error parsing NOTIFY body: \"".concat(request.body, "\""));
return;
}
switch (true) {
case /^100$/.test(status_line.status_code):
this.emit('trying', {
request: request,
status_line: status_line
});
break;
case /^1[0-9]{2}$/.test(status_line.status_code):
this.emit('progress', {
request: request,
status_line: status_line
});
break;
case /^2[0-9]{2}$/.test(status_line.status_code):
this.emit('accepted', {
request: request,
status_line: status_line
});
break;
default:
this.emit('failed', {
request: request,
status_line: status_line
});
break;
}
}
}, {
key: "_requestSucceeded",
value: function _requestSucceeded(response) {
logger.debug('REFER succeeded');
logger.debug('emit "requestSucceeded"');
this.emit('requestSucceeded', {
response: response
});
}
}, {
key: "_requestFailed",
value: function _requestFailed(response, cause) {
logger.debug('REFER failed');
logger.debug('emit "requestFailed"');
this.emit('requestFailed', {
response: response || null,
cause: cause
});
}
}, {
key: "id",
get: function get() {
return this._id;
}
}]);
return ReferSubscriber;
}(EventEmitter);
},{"../Constants":2,"../Grammar":7,"../Logger":9,"../Utils":28,"events":31}],19:[function(require,module,exports){
"use strict";
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }
var Logger = require('./Logger');
var Utils = require('./Utils');
var SimpleSIP_C = require('./Constants');
var SIPMessage = require('./SIPMessage');
var RequestSender = require('./RequestSender');
var logger = new Logger('Registrator');
var MIN_REGISTER_EXPIRES = 10; // In seconds.
module.exports = /*#__PURE__*/function () {
function Registrator(ua, transport) {
_classCallCheck(this, Registrator);
// Force reg_id to 1.
this._reg_id = 1;
this._ua = ua;
this._transport = transport;
this._registrar = ua.configuration.registrar_server;
this._expires = ua.configuration.register_expires; // Call-ID and CSeq values RFC3261 10.2.
this._call_id = Utils.createRandomToken(22);
this._cseq = 0;
this._to_uri = ua.configuration.uri;
this._registrationTimer = null; // Ongoing Register request.
this._registering = false; // Set status.
this._registered = false; // Contact header.
this._contact = this._ua.contact.toString(); // Sip.ice media feature tag (RFC 5768).
this._contact += ';+sip.ice'; // Custom headers for REGISTER and un-REGISTER.
this._extraHeaders = []; // Custom Contact header params for REGISTER and un-REGISTER.
this._extraContactParams = ''; // Contents of the sip.instance Contact header parameter.
this._sipInstance = "\"<urn:uuid:".concat(this._ua.configuration.instance_id, ">\"");
this._contact += ";reg-id=".concat(this._reg_id);
this._contact += ";+sip.instance=".concat(this._sipInstance);
}
_createClass(Registrator, [{
key: "setExtraHeaders",
value: function setExtraHeaders(extraHeaders) {
if (!Array.isArray(extraHeaders)) {
extraHeaders = [];
}
this._extraHeaders = extraHeaders.slice();
}
}, {
key: "setExtraContactParams",
value: function setExtraContactParams(extraContactParams) {
if (!(extraContactParams instanceof Object)) {
extraContactParams = {};
} // Reset it.
this._extraContactParams = '';
for (var param_key in extraContactParams) {
if (Object.prototype.hasOwnProperty.call(extraContactParams, param_key)) {
var param_value = extraContactParams[param_key];
this._extraContactParams += ";".concat(param_key);
if (param_value) {
this._extraContactParams += "=".concat(param_value);
}
}
}
}
}, {
key: "register",
value: function register() {
var _this = this;
if (this._registering) {
logger.debug('Register request in progress...');
return;
}
var extraHeaders = this._extraHeaders.slice();
extraHeaders.push("Contact: ".concat(this._contact, ";expires=").concat(this._expires).concat(this._extraContactParams));
extraHeaders.push("Expires: ".concat(this._expires));
var request = new SIPMessage.OutgoingRequest(SimpleSIP_C.REGISTER, this._registrar, this._ua, {
'to_uri': this._to_uri,
'call_id': this._call_id,
'cseq': this._cseq += 1
}, extraHeaders);
var request_sender = new RequestSender(this._ua, request, {
onRequestTimeout: function onRequestTimeout() {
_this._registrationFailure(null, SimpleSIP_C.causes.REQUEST_TIMEOUT);
},
onTransportError: function onTransportError() {
_this._registrationFailure(null, SimpleSIP_C.causes.CONNECTION_ERROR);
},
// Increase the CSeq on authentication.
onAuthenticated: function onAuthenticated() {
_this._cseq += 1;
},
onReceiveResponse: function onReceiveResponse(response) {
// Discard responses to older REGISTER/un-REGISTER requests.
if (response.cseq !== _this._cseq) {
return;
} // Clear registration timer.
if (_this._registrationTimer !== null) {
clearTimeout(_this._registrationTimer);
_this._registrationTimer = null;
}
switch (true) {
case /^1[0-9]{2}$/.test(response.status_code):
{
// Ignore provisional responses.
break;
}
case /^2[0-9]{2}$/.test(response.status_code):
{
_this._registering = false;
if (!response.hasHeader('Contact')) {
logger.debug('no Contact header in response to REGISTER, response ignored');
break;
}
var contacts = response.headers['Contact'].reduce(function (a, b) {
return a.concat(b.parsed);
}, []); // Get the Contact pointing to us and update the expires value accordingly.
// Try to find a matching Contact using sip.instance and reg-id.
var contact = contacts.find(function (element) {
return _this._sipInstance === element.getParam('+sip.instance') && _this._reg_id === parseInt(element.getParam('reg-id'));
}); // If no match was found using the sip.instance try comparing the URIs.
if (!contact) {
contact = contacts.find(function (element) {
return element.uri.user === _this._ua.contact.uri.user;
});
}
if (!contact) {
logger.debug('no Contact header pointing to us, response ignored');
break;
}
var expires = contact.getParam('expires');
if (!expires && response.hasHeader('expires')) {
expires = response.getHeader('expires');
}
if (!expires) {
expires = _this._expires;
}
expires = Number(expires);
if (expires < MIN_REGISTER_EXPIRES) expires = MIN_REGISTER_EXPIRES;
var timeout = expires > 64 ? expires * 1000 / 2 + Math.floor((expires / 2 - 32) * 1000 * Math.random()) : expires * 1000 - 5000; // Re-Register or emit an event before the expiration interval has elapsed.
// For that, decrease the expires value. ie: 3 seconds.
_this._registrationTimer = setTimeout(function () {
_this._registrationTimer = null; // If there are no listeners for registrationExpiring, renew registration.
// If there are listeners, let the function listening do the register call.
if (_this._ua.listeners('registrationExpiring').length === 0) {
_this.register();
} else {
_this._ua.emit('registrationExpiring');
}
}, timeout); // Save gruu values.
if (contact.hasParam('temp-gruu')) {
_this._ua.contact.temp_gruu = contact.getParam('temp-gruu').replace(/"/g, '');
}
if (contact.hasParam('pub-gruu')) {
_this._ua.contact.pub_gruu = contact.getParam('pub-gruu').replace(/"/g, '');
}
if (!_this._registered) {
_this._registered = true;
_this._ua.registered({
response: response
});
}
break;
}
// Interval too brief RFC3261 10.2.8.
case /^423$/.test(response.status_code):
{
if (response.hasHeader('min-expires')) {
// Increase our registration interval to the suggested minimum.
_this._expires = Number(response.getHeader('min-expires'));
if (_this._expires < MIN_REGISTER_EXPIRES) _this._expires = MIN_REGISTER_EXPIRES; // Attempt the registration again immediately.
_this.register();
} else {
// This response MUST contain a Min-Expires header field.
logger.debug('423 response received for REGISTER without Min-Expires');
_this._registrationFailure(response, SimpleSIP_C.causes.SIP_FAILURE_CODE);
}
break;
}
default:
{
var cause = Utils.sipErrorCause(response.status_code);
_this._registrationFailure(response, cause);
}
}
}
});
this._registering = true;
request_sender.send();
}
}, {
key: "unregister",
value: function unregister() {
var _this2 = this;
var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
if (!this._registered) {
logger.debug('already unregistered');
return;
}
this._registered = false; // Clear the registration timer.
if (this._registrationTimer !== null) {
clearTimeout(this._registrationTimer);
this._registrationTimer = null;
}
var extraHeaders = this._extraHeaders.slice();
if (options.all) {
extraHeaders.push("Contact: *".concat(this._extraContactParams));
} else {
extraHeaders.push("Contact: ".concat(this._contact, ";expires=0").concat(this._extraContactParams));
}
extraHeaders.push('Expires: 0');
var request = new SIPMessage.OutgoingRequest(SimpleSIP_C.REGISTER, this._registrar, this._ua, {
'to_uri': this._to_uri,
'call_id': this._call_id,
'cseq': this._cseq += 1
}, extraHeaders);
var request_sender = new RequestSender(this._ua, request, {
onRequestTimeout: function onRequestTimeout() {
_this2._unregistered(null, SimpleSIP_C.causes.REQUEST_TIMEOUT);
},
onTransportError: function onTransportError() {
_this2._unregistered(null, SimpleSIP_C.causes.CONNECTION_ERROR);
},
// Increase the CSeq on authentication.
onAuthenticated: function onAuthenticated() {
_this2._cseq += 1;
},
onReceiveResponse: function onReceiveResponse(response) {
switch (true) {
case /^1[0-9]{2}$/.test(response.status_code):
// Ignore provisional responses.
break;
case /^2[0-9]{2}$/.test(response.status_code):
_this2._unregistered(response);
break;
default:
{
var cause = Utils.sipErrorCause(response.status_code);
_this2._unregistered(response, cause);
}
}
}
});
request_sender.send();
}
}, {
key: "close",
value: function close() {
if (this._registered) {
this.unregister();
}
}
}, {
key: "onTransportClosed",
value: function onTransportClosed() {
this._registering = false;
if (this._registrationTimer !== null) {
clearTimeout(this._registrationTimer);
this._registrationTimer = null;
}
if (this._registered) {
this._registered = false;
this._ua.unregistered({});
}
}
}, {
key: "_registrationFailure",
value: function _registrationFailure(response, cause) {
this._registering = false;
this._ua.registrationFailed({
response: response || null,
cause: cause
});
if (this._registered) {
this._registered = false;
this._ua.unregistered({
response: response || null,
cause: cause
});
}
}
}, {
key: "_unregistered",
value: function _unregistered(response, cause) {
this._registering = false;
this._registered = false;
this._ua.unregistered({
response: response || null,
cause: cause || null
});
}
}, {
key: "registered",
get: function get() {
return this._registered;
}
}]);
return Registrator;
}();
},{"./Constants":2,"./Logger":9,"./RequestSender":20,"./SIPMessage":21,"./Utils":28}],20:[function(require,module,exports){
"use strict";
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }
var Logger = require('./Logger');
var SimpleSIP_C = require('./Constants');
var DigestAuthentication = require('./DigestAuthentication');
var Transactions = require('./Transactions');
var logger = new Logger('RequestSender'); // Default event handlers.
var EventHandlers = {
onRequestTimeout: function onRequestTimeout() {},
onTransportError: function onTransportError() {},
onReceiveResponse: function onReceiveResponse() {},
onAuthenticated: function onAuthenticated() {}
};
module.exports = /*#__PURE__*/function () {
function RequestSender(ua, request, eventHandlers) {
_classCallCheck(this, RequestSender);
this._ua = ua;
this._eventHandlers = eventHandlers;
this._method = request.method;
this._request = request;
this._auth = null;
this._challenged = false;
this._staled = false; // Define the undefined handlers.
for (var handler in EventHandlers) {
if (Object.prototype.hasOwnProperty.call(EventHandlers, handler)) {
if (!this._eventHandlers[handler]) {
this._eventHandlers[handler] = EventHandlers[handler];
}
}
} // If ua is in closing process or even closed just allow sending Bye and ACK.
if (ua.status === ua.C.STATUS_USER_CLOSED && (this._method !== SimpleSIP_C.BYE || this._method !== SimpleSIP_C.ACK)) {
this._eventHandlers.onTransportError();
}
}
/**
* Create the client transaction and send the message.
*/
_createClass(RequestSender, [{
key: "send",
value: function send() {
var _this = this;
var eventHandlers = {
onRequestTimeout: function onRequestTimeout() {
_this._eventHandlers.onRequestTimeout();
},
onTransportError: function onTransportError() {
_this._eventHandlers.onTransportError();
},
onReceiveResponse: function onReceiveResponse(response) {
_this._receiveResponse(response);
}
};
switch (this._method) {
case 'INVITE':
this.clientTransaction = new Transactions.InviteClientTransaction(this._ua, this._ua.transport, this._request, eventHandlers);
break;
case 'ACK':
this.clientTransaction = new Transactions.AckClientTransaction(this._ua, this._ua.transport, this._request, eventHandlers);
break;
default:
this.clientTransaction = new Transactions.NonInviteClientTransaction(this._ua, this._ua.transport, this._request, eventHandlers);
} // If authorization JWT is present, use it.
if (this._ua._configuration.authorization_jwt) {
this._request.setHeader('Authorization', this._ua._configuration.authorization_jwt);
}
this.clientTransaction.send();
}
/**
* Called from client transaction when receiving a correct response to the request.
* Authenticate request if needed or pass the response back to the applicant.
*/
}, {
key: "_receiveResponse",
value: function _receiveResponse(response) {
var challenge;
var authorization_header_name;
var status_code = response.status_code;
/*
* Authentication
* Authenticate once. _challenged_ flag used to avoid infinite authentications.
*/
if ((status_code === 401 || status_code === 407) && (this._ua.configuration.password !== null || this._ua.configuration.ha1 !== null)) {
// Get and parse the appropriate WWW-Authenticate or Proxy-Authenticate header.
if (response.status_code === 401) {
challenge = response.parseHeader('www-authenticate');
authorization_header_name = 'authorization';
} else {
challenge = response.parseHeader('proxy-authenticate');
authorization_header_name = 'proxy-authorization';
} // Verify it seems a valid challenge.
if (!challenge) {
logger.debug("".concat(response.status_code, " with wrong or missing challenge, cannot authenticate"));
this._eventHandlers.onReceiveResponse(response);
return;
}
if (!this._challenged || !this._staled && challenge.stale === true) {
if (!this._auth) {
this._auth = new DigestAuthentication({
username: this._ua.configuration.authorization_user,
password: this._ua.configuration.password,
realm: this._ua.configuration.realm,
ha1: this._ua.configuration.ha1
});
} // Verify that the challenge is really valid.
if (!this._auth.authenticate(this._request, challenge)) {
this._eventHandlers.onReceiveResponse(response);
return;
}
this._challenged = true; // Update ha1 and realm in the UA.
this._ua.set('realm', this._auth.get('realm'));
this._ua.set('ha1', this._auth.get('ha1'));
if (challenge.stale) {
this._staled = true;
}
this._request = this._request.clone();
this._request.cseq += 1;
this._request.setHeader('cseq', "".concat(this._request.cseq, " ").concat(this._method));
this._request.setHeader(authorization_header_name, this._auth.toString());
this._eventHandlers.onAuthenticated(this._request);
this.send();
} else {
this._eventHandlers.onReceiveResponse(response);
}
} else {
this._eventHandlers.onReceiveResponse(response);
}
}
}]);
return RequestSender;
}();
},{"./Constants":2,"./DigestAuthentication":5,"./Logger":9,"./Transactions":24}],21:[function(require,module,exports){
"use strict";
function _typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); if (superClass) _setPrototypeOf(subClass, superClass); }
function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }
function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; }
function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === "object" || typeof call === "function")) { return call; } return _assertThisInitialized(self); }
function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; }
function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); return true; } catch (e) { return false; } }
function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }
function _createForOfIteratorHelper(o, allowArrayLike) { var it; if (typeof Symbol === "undefined" || o[Symbol.iterator] == null) { if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = o[Symbol.iterator](); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it["return"] != null) it["return"](); } finally { if (didErr) throw err; } } }; }
function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }
var sdp_transform = require('sdp-transform');
var Logger = require('./Logger');
var SimpleSIP_C = require('./Constants');
var Utils = require('./Utils');
var NameAddrHeader = require('./NameAddrHeader');
var Grammar = require('./Grammar');
var logger = new Logger('SIPMessage');
/**
* -param {String} method request method
* -param {String} ruri request uri
* -param {UA} ua
* -param {Object} params parameters that will have priority over ua.configuration parameters:
* <br>
* - cseq, call_id, from_tag, from_uri, from_display_name, to_uri, to_tag, route_set
* -param {Object} [headers] extra headers
* -param {String} [body]
*/
var OutgoingRequest = /*#__PURE__*/function () {
function OutgoingRequest(method, ruri, ua, params, extraHeaders, body) {
_classCallCheck(this, OutgoingRequest);
// Mandatory parameters check.
if (!method || !ruri || !ua) {
return null;
}
params = params || {};
this.ua = ua;
this.headers = {};
this.method = method;
this.ruri = ruri;
this.body = body;
this.extraHeaders = Utils.cloneArray(extraHeaders);
if (this.ua.configuration.extra_headers) {
this.extraHeaders = this.extraHeaders.concat(this.ua.configuration.extra_headers);
} // Fill the Common SIP Request Headers.
// Route.
if (params.route_set) {
this.setHeader('route', params.route_set);
} else if (ua.configuration.use_preloaded_route) {
this.setHeader('route', "<".concat(ua.transport.sip_uri, ";lr>"));
} // Via.
// Empty Via header. Will be filled by the client transaction.
this.setHeader('via', ''); // Max-Forwards.
this.setHeader('max-forwards', SimpleSIP_C.MAX_FORWARDS); // To
var to_uri = params.to_uri || ruri;
var to_params = params.to_tag ? {
tag: params.to_tag
} : null;
var to_display_name = typeof params.to_display_name !== 'undefined' ? params.to_display_name : null;
this.to = new NameAddrHeader(to_uri, to_display_name, to_params);
this.setHeader('to', this.to.toString()); // From.
var from_uri = params.from_uri || ua.configuration.uri;
var from_params = {
tag: params.from_tag || Utils.newTag()
};
var display_name;
if (typeof params.from_display_name !== 'undefined') {
display_name = params.from_display_name;
} else if (ua.configuration.display_name) {
display_name = ua.configuration.display_name;
} else {
display_name = null;
}
this.from = new NameAddrHeader(from_uri, display_name, from_params);
this.setHeader('from', this.from.toString()); // Call-ID.
var call_id = params.call_id || ua.configuration.SimpleSIP_id + Utils.createRandomToken(15);
this.call_id = call_id;
this.setHeader('call-id', call_id); // CSeq.
var cseq = params.cseq || Math.floor(Math.random() * 10000);
this.cseq = cseq;
this.setHeader('cseq', "".concat(cseq, " ").concat(method));
}
/**
* Replace the the given header by the given value.
* -param {String} name header name
* -param {String | Array} value header value
*/
_createClass(OutgoingRequest, [{
key: "setHeader",
value: function setHeader(name, value) {
// Remove the header from extraHeaders if present.
var regexp = new RegExp("^\\s*".concat(name, "\\s*:"), 'i');
for (var idx = 0; idx < this.extraHeaders.length; idx++) {
if (regexp.test(this.extraHeaders[idx])) {
this.extraHeaders.splice(idx, 1);
}
}
this.headers[Utils.headerize(name)] = Array.isArray(value) ? value : [value];
}
/**
* Get the value of the given header name at the given position.
* -param {String} name header name
* -returns {String|undefined} Returns the specified header, null if header doesn't exist.
*/
}, {
key: "getHeader",
value: function getHeader(name) {
var headers = this.headers[Utils.headerize(name)];
if (headers) {
if (headers[0]) {
return headers[0];
}
} else {
var regexp = new RegExp("^\\s*".concat(name, "\\s*:"), 'i');
var _iterator = _createForOfIteratorHelper(this.extraHeaders),
_step;
try {
for (_iterator.s(); !(_step = _iterator.n()).done;) {
var header = _step.value;
if (regexp.test(header)) {
return header.substring(header.indexOf(':') + 1).trim();
}
}
} catch (err) {
_iterator.e(err);
} finally {
_iterator.f();
}
}
return;
}
/**
* Get the header/s of the given name.
* -param {String} name header name
* -returns {Array} Array with all the headers of the specified name.
*/
}, {
key: "getHeaders",
value: function getHeaders(name) {
var headers = this.headers[Utils.headerize(name)];
var result = [];
if (headers) {
var _iterator2 = _createForOfIteratorHelper(headers),
_step2;
try {
for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
var header = _step2.value;
result.push(header);
}
} catch (err) {
_iterator2.e(err);
} finally {
_iterator2.f();
}
return result;
} else {
var regexp = new RegExp("^\\s*".concat(name, "\\s*:"), 'i');
var _iterator3 = _createForOfIteratorHelper(this.extraHeaders),
_step3;
try {
for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) {
var _header = _step3.value;
if (regexp.test(_header)) {
result.push(_header.substring(_header.indexOf(':') + 1).trim());
}
}
} catch (err) {
_iterator3.e(err);
} finally {
_iterator3.f();
}
return result;
}
}
/**
* Verify the existence of the given header.
* -param {String} name header name
* -returns {boolean} true if header with given name exists, false otherwise
*/
}, {
key: "hasHeader",
value: function hasHeader(name) {
if (this.headers[Utils.headerize(name)]) {
return true;
} else {
var regexp = new RegExp("^\\s*".concat(name, "\\s*:"), 'i');
var _iterator4 = _createForOfIteratorHelper(this.extraHeaders),
_step4;
try {
for (_iterator4.s(); !(_step4 = _iterator4.n()).done;) {
var header = _step4.value;
if (regexp.test(header)) {
return true;
}
}
} catch (err) {
_iterator4.e(err);
} finally {
_iterator4.f();
}
}
return false;
}
/**
* Parse the current body as a SDP and store the resulting object
* into this.sdp.
* -param {Boolean} force: Parse even if this.sdp already exists.
*
* Returns this.sdp.
*/
}, {
key: "parseSDP",
value: function parseSDP(force) {
if (!force && this.sdp) {
return this.sdp;
} else {
this.sdp = sdp_transform.parse(this.body || '');
return this.sdp;
}
}
}, {
key: "toString",
value: function toString() {
var msg = "".concat(this.method, " ").concat(this.ruri, " SIP/2.0\r\n");
for (var headerName in this.headers) {
if (Object.prototype.hasOwnProperty.call(this.headers, headerName)) {
var _iterator5 = _createForOfIteratorHelper(this.headers[headerName]),
_step5;
try {
for (_iterator5.s(); !(_step5 = _iterator5.n()).done;) {
var headerValue = _step5.value;
msg += "".concat(headerName, ": ").concat(headerValue, "\r\n");
}
} catch (err) {
_iterator5.e(err);
} finally {
_iterator5.f();
}
}
}
var _iterator6 = _createForOfIteratorHelper(this.extraHeaders),
_step6;
try {
for (_iterator6.s(); !(_step6 = _iterator6.n()).done;) {
var header = _step6.value;
msg += "".concat(header.trim(), "\r\n");
} // Supported.
} catch (err) {
_iterator6.e(err);
} finally {
_iterator6.f();
}
var supported = [];
switch (this.method) {
case SimpleSIP_C.REGISTER:
supported.push('path', 'gruu');
break;
case SimpleSIP_C.INVITE:
if (this.ua.configuration.session_timers) {
supported.push('timer');
}
if (this.ua.contact.pub_gruu || this.ua.contact.temp_gruu) {
supported.push('gruu');
}
supported.push('ice', 'replaces');
break;
case SimpleSIP_C.UPDATE:
if (this.ua.configuration.session_timers) {
supported.push('timer');
}
supported.push('ice');
break;
}
supported.push('outbound');
var userAgent = this.ua.configuration.user_agent || SimpleSIP_C.USER_AGENT; // Allow.
msg += "Allow: ".concat(SimpleSIP_C.ALLOWED_METHODS, "\r\n");
msg += "Supported: ".concat(supported, "\r\n");
msg += "User-Agent: ".concat(userAgent, "\r\n");
if (this.body) {
var length = Utils.str_utf8_length(this.body);
msg += "Content-Length: ".concat(length, "\r\n\r\n");
msg += this.body;
} else {
msg += 'Content-Length: 0\r\n\r\n';
}
return msg;
}
}, {
key: "clone",
value: function clone() {
var request = new OutgoingRequest(this.method, this.ruri, this.ua);
Object.keys(this.headers).forEach(function (name) {
request.headers[name] = this.headers[name].slice();
}, this);
request.body = this.body;
request.extraHeaders = Utils.cloneArray(this.extraHeaders);
request.to = this.to;
request.from = this.from;
request.call_id = this.call_id;
request.cseq = this.cseq;
return request;
}
}]);
return OutgoingRequest;
}();
var InitialOutgoingInviteRequest = /*#__PURE__*/function (_OutgoingRequest) {
_inherits(InitialOutgoingInviteRequest, _OutgoingRequest);
var _super = _createSuper(InitialOutgoingInviteRequest);
function InitialOutgoingInviteRequest(ruri, ua, params, extraHeaders, body) {
var _this;
_classCallCheck(this, InitialOutgoingInviteRequest);
_this = _super.call(this, SimpleSIP_C.INVITE, ruri, ua, params, extraHeaders, body);
_this.transaction = null;
return _this;
}
_createClass(InitialOutgoingInviteRequest, [{
key: "cancel",
value: function cancel(reason) {
this.transaction.cancel(reason);
}
}, {
key: "clone",
value: function clone() {
var request = new InitialOutgoingInviteRequest(this.ruri, this.ua);
Object.keys(this.headers).forEach(function (name) {
request.headers[name] = this.headers[name].slice();
}, this);
request.body = this.body;
request.extraHeaders = Utils.cloneArray(this.extraHeaders);
request.to = this.to;
request.from = this.from;
request.call_id = this.call_id;
request.cseq = this.cseq;
request.transaction = this.transaction;
return request;
}
}]);
return InitialOutgoingInviteRequest;
}(OutgoingRequest);
var IncomingMessage = /*#__PURE__*/function () {
function IncomingMessage() {
_classCallCheck(this, IncomingMessage);
this.data = null;
this.headers = null;
this.method = null;
this.via = null;
this.via_branch = null;
this.call_id = null;
this.cseq = null;
this.from = null;
this.from_tag = null;
this.to = null;
this.to_tag = null;
this.body = null;
this.sdp = null;
}
/**
* Insert a header of the given name and value into the last position of the
* header array.
*/
_createClass(IncomingMessage, [{
key: "addHeader",
value: function addHeader(name, value) {
var header = {
raw: value
};
name = Utils.headerize(name);
if (this.headers[name]) {
this.headers[name].push(header);
} else {
this.headers[name] = [header];
}
}
/**
* Get the value of the given header name at the given position.
*/
}, {
key: "getHeader",
value: function getHeader(name) {
var header = this.headers[Utils.headerize(name)];
if (header) {
if (header[0]) {
return header[0].raw;
}
} else {
return;
}
}
/**
* Get the header/s of the given name.
*/
}, {
key: "getHeaders",
value: function getHeaders(name) {
var headers = this.headers[Utils.headerize(name)];
var result = [];
if (!headers) {
return [];
}
var _iterator7 = _createForOfIteratorHelper(headers),
_step7;
try {
for (_iterator7.s(); !(_step7 = _iterator7.n()).done;) {
var header = _step7.value;
result.push(header.raw);
}
} catch (err) {
_iterator7.e(err);
} finally {
_iterator7.f();
}
return result;
}
/**
* Verify the existence of the given header.
*/
}, {
key: "hasHeader",
value: function hasHeader(name) {
return this.headers[Utils.headerize(name)] ? true : false;
}
/**
* Parse the given header on the given index.
* -param {String} name header name
* -param {Number} [idx=0] header index
* -returns {Object|undefined} Parsed header object, undefined if the header
* is not present or in case of a parsing error.
*/
}, {
key: "parseHeader",
value: function parseHeader(name) {
var idx = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;
name = Utils.headerize(name);
if (!this.headers[name]) {
logger.debug("header \"".concat(name, "\" not present"));
return;
} else if (idx >= this.headers[name].length) {
logger.debug("not so many \"".concat(name, "\" headers present"));
return;
}
var header = this.headers[name][idx];
var value = header.raw;
if (header.parsed) {
return header.parsed;
} // Substitute '-' by '_' for grammar rule matching.
var parsed = Grammar.parse(value, name.replace(/-/g, '_'));
if (parsed === -1) {
this.headers[name].splice(idx, 1); // delete from headers
logger.debug("error parsing \"".concat(name, "\" header field with value \"").concat(value, "\""));
return;
} else {
header.parsed = parsed;
return parsed;
}
}
/**
* Message Header attribute selector. Alias of parseHeader.
* -param {String} name header name
* -param {Number} [idx=0] header index
* -returns {Object|undefined} Parsed header object, undefined if the header
* is not present or in case of a parsing error.
*
* -example
* message.s('via',3).port
*/
}, {
key: "s",
value: function s(name, idx) {
return this.parseHeader(name, idx);
}
/**
* Replace the value of the given header by the value.
* -param {String} name header name
* -param {String} value header value
*/
}, {
key: "setHeader",
value: function setHeader(name, value) {
var header = {
raw: value
};
this.headers[Utils.headerize(name)] = [header];
}
/**
* Parse the current body as a SDP and store the resulting object
* into this.sdp.
* -param {Boolean} force: Parse even if this.sdp already exists.
*
* Returns this.sdp.
*/
}, {
key: "parseSDP",
value: function parseSDP(force) {
if (!force && this.sdp) {
return this.sdp;
} else {
this.sdp = sdp_transform.parse(this.body || '');
return this.sdp;
}
}
}, {
key: "toString",
value: function toString() {
return this.data;
}
}]);
return IncomingMessage;
}();
var IncomingRequest = /*#__PURE__*/function (_IncomingMessage) {
_inherits(IncomingRequest, _IncomingMessage);
var _super2 = _createSuper(IncomingRequest);
function IncomingRequest(ua) {
var _this2;
_classCallCheck(this, IncomingRequest);
_this2 = _super2.call(this);
_this2.ua = ua;
_this2.headers = {};
_this2.ruri = null;
_this2.transport = null;
_this2.server_transaction = null;
return _this2;
}
/**
* Stateful reply.
* -param {Number} code status code
* -param {String} reason reason phrase
* -param {Object} headers extra headers
* -param {String} body body
* -param {Function} [onSuccess] onSuccess callback
* -param {Function} [onFailure] onFailure callback
*/
_createClass(IncomingRequest, [{
key: "reply",
value: function reply(code, reason, extraHeaders, body, onSuccess, onFailure) {
var supported = [];
var to = this.getHeader('To');
code = code || null;
reason = reason || null; // Validate code and reason values.
if (!code || code < 100 || code > 699) {
throw new TypeError("Invalid status_code: ".concat(code));
} else if (reason && typeof reason !== 'string' && !(reason instanceof String)) {
throw new TypeError("Invalid reason_phrase: ".concat(reason));
}
reason = reason || SimpleSIP_C.REASON_PHRASE[code] || '';
extraHeaders = Utils.cloneArray(extraHeaders);
if (this.ua.configuration.extra_headers) {
extraHeaders = extraHeaders.concat(this.ua.configuration.extra_headers);
}
var response = "SIP/2.0 ".concat(code, " ").concat(reason, "\r\n");
if (this.method === SimpleSIP_C.INVITE && code > 100 && code <= 200) {
var headers = this.getHeaders('record-route');
var _iterator8 = _createForOfIteratorHelper(headers),
_step8;
try {
for (_iterator8.s(); !(_step8 = _iterator8.n()).done;) {
var header = _step8.value;
response += "Record-Route: ".concat(header, "\r\n");
}
} catch (err) {
_iterator8.e(err);
} finally {
_iterator8.f();
}
}
var vias = this.getHeaders('via');
var _iterator9 = _createForOfIteratorHelper(vias),
_step9;
try {
for (_iterator9.s(); !(_step9 = _iterator9.n()).done;) {
var via = _step9.value;
response += "Via: ".concat(via, "\r\n");
}
} catch (err) {
_iterator9.e(err);
} finally {
_iterator9.f();
}
if (!this.to_tag && code > 100) {
to += ";tag=".concat(Utils.newTag());
} else if (this.to_tag && !this.s('to').hasParam('tag')) {
to += ";tag=".concat(this.to_tag);
}
response += "To: ".concat(to, "\r\n");
response += "From: ".concat(this.getHeader('From'), "\r\n");
response += "Call-ID: ".concat(this.call_id, "\r\n");
response += "CSeq: ".concat(this.cseq, " ").concat(this.method, "\r\n");
var _iterator10 = _createForOfIteratorHelper(extraHeaders),
_step10;
try {
for (_iterator10.s(); !(_step10 = _iterator10.n()).done;) {
var _header2 = _step10.value;
response += "".concat(_header2.trim(), "\r\n");
} // Supported.
} catch (err) {
_iterator10.e(err);
} finally {
_iterator10.f();
}
switch (this.method) {
case SimpleSIP_C.INVITE:
if (this.ua.configuration.session_timers) {
supported.push('timer');
}
if (this.ua.contact.pub_gruu || this.ua.contact.temp_gruu) {
supported.push('gruu');
}
supported.push('ice', 'replaces');
break;
case SimpleSIP_C.UPDATE:
if (this.ua.configuration.session_timers) {
supported.push('timer');
}
if (body) {
supported.push('ice');
}
supported.push('replaces');
}
supported.push('outbound'); // Allow and Accept.
if (this.method === SimpleSIP_C.OPTIONS) {
response += "Allow: ".concat(SimpleSIP_C.ALLOWED_METHODS, "\r\n");
response += "Accept: ".concat(SimpleSIP_C.ACCEPTED_BODY_TYPES, "\r\n");
} else if (code === 405) {
response += "Allow: ".concat(SimpleSIP_C.ALLOWED_METHODS, "\r\n");
} else if (code === 415) {
response += "Accept: ".concat(SimpleSIP_C.ACCEPTED_BODY_TYPES, "\r\n");
}
response += "Supported: ".concat(supported, "\r\n");
if (body) {
var length = Utils.str_utf8_length(body);
response += 'Content-Type: application/sdp\r\n';
response += "Content-Length: ".concat(length, "\r\n\r\n");
response += body;
} else {
response += "Content-Length: ".concat(0, "\r\n\r\n");
}
this.server_transaction.receiveResponse(code, response, onSuccess, onFailure);
}
/**
* Stateless reply.
* -param {Number} code status code
* -param {String} reason reason phrase
*/
}, {
key: "reply_sl",
value: function reply_sl() {
var code = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null;
var reason = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;
var vias = this.getHeaders('via'); // Validate code and reason values.
if (!code || code < 100 || code > 699) {
throw new TypeError("Invalid status_code: ".concat(code));
} else if (reason && typeof reason !== 'string' && !(reason instanceof String)) {
throw new TypeError("Invalid reason_phrase: ".concat(reason));
}
reason = reason || SimpleSIP_C.REASON_PHRASE[code] || '';
var response = "SIP/2.0 ".concat(code, " ").concat(reason, "\r\n");
var _iterator11 = _createForOfIteratorHelper(vias),
_step11;
try {
for (_iterator11.s(); !(_step11 = _iterator11.n()).done;) {
var via = _step11.value;
response += "Via: ".concat(via, "\r\n");
}
} catch (err) {
_iterator11.e(err);
} finally {
_iterator11.f();
}
var to = this.getHeader('To');
if (!this.to_tag && code > 100) {
to += ";tag=".concat(Utils.newTag());
} else if (this.to_tag && !this.s('to').hasParam('tag')) {
to += ";tag=".concat(this.to_tag);
}
response += "To: ".concat(to, "\r\n");
response += "From: ".concat(this.getHeader('From'), "\r\n");
response += "Call-ID: ".concat(this.call_id, "\r\n");
response += "CSeq: ".concat(this.cseq, " ").concat(this.method, "\r\n");
if (this.ua.configuration.extra_headers) {
var _iterator12 = _createForOfIteratorHelper(this.ua.configuration.extra_headers),
_step12;
try {
for (_iterator12.s(); !(_step12 = _iterator12.n()).done;) {
var header = _step12.value;
response += "".concat(header.trim(), "\r\n");
}
} catch (err) {
_iterator12.e(err);
} finally {
_iterator12.f();
}
}
response += "Content-Length: ".concat(0, "\r\n\r\n");
this.transport.send(response);
}
}]);
return IncomingRequest;
}(IncomingMessage);
var IncomingResponse = /*#__PURE__*/function (_IncomingMessage2) {
_inherits(IncomingResponse, _IncomingMessage2);
var _super3 = _createSuper(IncomingResponse);
function IncomingResponse() {
var _this3;
_classCallCheck(this, IncomingResponse);
_this3 = _super3.call(this);
_this3.headers = {};
_this3.status_code = null;
_this3.reason_phrase = null;
return _this3;
}
return IncomingResponse;
}(IncomingMessage);
module.exports = {
OutgoingRequest: OutgoingRequest,
InitialOutgoingInviteRequest: InitialOutgoingInviteRequest,
IncomingRequest: IncomingRequest,
IncomingResponse: IncomingResponse
};
},{"./Constants":2,"./Grammar":7,"./Logger":9,"./NameAddrHeader":11,"./Utils":28,"sdp-transform":37}],22:[function(require,module,exports){
"use strict";
var Logger = require('./Logger');
var Utils = require('./Utils');
var Grammar = require('./Grammar');
var logger = new Logger('Socket');
/**
* Interface documentation: https://SimpleSIP.net/documentation/$last_version/api/socket/
*
* interface Socket {
* attribute String via_transport
* attribute String url
* attribute String sip_uri
*
* method connect();
* method disconnect();
* method send(data);
*
* attribute EventHandler onconnect
* attribute EventHandler ondisconnect
* attribute EventHandler ondata
* }
*
*/
exports.isSocket = function (socket) {
// Ignore if an array is given.
if (Array.isArray(socket)) {
return false;
}
if (typeof socket === 'undefined') {
logger.warn('undefined SimpleSIP.Socket instance');
return false;
} // Check Properties.
try {
if (!Utils.isString(socket.url)) {
logger.warn('missing or invalid SimpleSIP.Socket url property');
throw new Error('Missing or invalid SimpleSIP.Socket url property');
}
if (!Utils.isString(socket.via_transport)) {
logger.warn('missing or invalid SimpleSIP.Socket via_transport property');
throw new Error('Missing or invalid SimpleSIP.Socket via_transport property');
}
if (Grammar.parse(socket.sip_uri, 'SIP_URI') === -1) {
logger.warn('missing or invalid SimpleSIP.Socket sip_uri property');
throw new Error('missing or invalid SimpleSIP.Socket sip_uri property');
}
} catch (e) {
return false;
} // Check Methods.
try {
['connect', 'disconnect', 'send'].forEach(function (method) {
if (!Utils.isFunction(socket[method])) {
logger.warn("missing or invalid SimpleSIP.Socket method: ".concat(method));
throw new Error("Missing or invalid SimpleSIP.Socket method: ".concat(method));
}
});
} catch (e) {
return false;
}
return true;
};
},{"./Grammar":7,"./Logger":9,"./Utils":28}],23:[function(require,module,exports){
"use strict";
var T1 = 500,
T2 = 4000,
T4 = 5000;
module.exports = {
T1: T1,
T2: T2,
T4: T4,
TIMER_B: 64 * T1,
TIMER_D: 0 * T1,
TIMER_F: 64 * T1,
TIMER_H: 64 * T1,
TIMER_I: 0 * T1,
TIMER_J: 0 * T1,
TIMER_K: 0 * T4,
TIMER_L: 64 * T1,
TIMER_M: 64 * T1,
PROVISIONAL_RESPONSE_INTERVAL: 60000 // See RFC 3261 Section 13.3.1.1
};
},{}],24:[function(require,module,exports){
"use strict";
function _typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); if (superClass) _setPrototypeOf(subClass, superClass); }
function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }
function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; }
function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === "object" || typeof call === "function")) { return call; } return _assertThisInitialized(self); }
function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; }
function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); return true; } catch (e) { return false; } }
function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }
var EventEmitter = require('events').EventEmitter;
var Logger = require('./Logger');
var SimpleSIP_C = require('./Constants');
var SIPMessage = require('./SIPMessage');
var Timers = require('./Timers');
var loggernict = new Logger('NonInviteClientTransaction');
var loggerict = new Logger('InviteClientTransaction');
var loggeract = new Logger('AckClientTransaction');
var loggernist = new Logger('NonInviteServerTransaction');
var loggerist = new Logger('InviteServerTransaction');
var C = {
// Transaction states.
STATUS_TRYING: 1,
STATUS_PROCEEDING: 2,
STATUS_CALLING: 3,
STATUS_ACCEPTED: 4,
STATUS_COMPLETED: 5,
STATUS_TERMINATED: 6,
STATUS_CONFIRMED: 7,
// Transaction types.
NON_INVITE_CLIENT: 'nict',
NON_INVITE_SERVER: 'nist',
INVITE_CLIENT: 'ict',
INVITE_SERVER: 'ist'
};
var NonInviteClientTransaction = /*#__PURE__*/function (_EventEmitter) {
_inherits(NonInviteClientTransaction, _EventEmitter);
var _super = _createSuper(NonInviteClientTransaction);
function NonInviteClientTransaction(ua, transport, request, eventHandlers) {
var _this;
_classCallCheck(this, NonInviteClientTransaction);
_this = _super.call(this);
_this.type = C.NON_INVITE_CLIENT;
_this.id = "z9hG4bK".concat(Math.floor(Math.random() * 10000000));
_this.ua = ua;
_this.transport = transport;
_this.request = request;
_this.eventHandlers = eventHandlers;
var via = "SIP/2.0/".concat(transport.via_transport);
via += " ".concat(ua.configuration.via_host, ";branch=").concat(_this.id);
_this.request.setHeader('via', via);
_this.ua.newTransaction(_assertThisInitialized(_this));
return _this;
}
_createClass(NonInviteClientTransaction, [{
key: "stateChanged",
value: function stateChanged(state) {
this.state = state;
this.emit('stateChanged');
}
}, {
key: "send",
value: function send() {
var _this2 = this;
this.stateChanged(C.STATUS_TRYING);
this.F = setTimeout(function () {
_this2.timer_F();
}, Timers.TIMER_F);
if (!this.transport.send(this.request)) {
this.onTransportError();
}
}
}, {
key: "onTransportError",
value: function onTransportError() {
loggernict.debug("transport error occurred, deleting transaction ".concat(this.id));
clearTimeout(this.F);
clearTimeout(this.K);
this.stateChanged(C.STATUS_TERMINATED);
this.ua.destroyTransaction(this);
this.eventHandlers.onTransportError();
}
}, {
key: "timer_F",
value: function timer_F() {
loggernict.debug("Timer F expired for transaction ".concat(this.id));
this.stateChanged(C.STATUS_TERMINATED);
this.ua.destroyTransaction(this);
this.eventHandlers.onRequestTimeout();
}
}, {
key: "timer_K",
value: function timer_K() {
this.stateChanged(C.STATUS_TERMINATED);
this.ua.destroyTransaction(this);
}
}, {
key: "receiveResponse",
value: function receiveResponse(response) {
var _this3 = this;
var status_code = response.status_code;
if (status_code < 200) {
switch (this.state) {
case C.STATUS_TRYING:
case C.STATUS_PROCEEDING:
this.stateChanged(C.STATUS_PROCEEDING);
this.eventHandlers.onReceiveResponse(response);
break;
}
} else {
switch (this.state) {
case C.STATUS_TRYING:
case C.STATUS_PROCEEDING:
this.stateChanged(C.STATUS_COMPLETED);
clearTimeout(this.F);
if (status_code === 408) {
this.eventHandlers.onRequestTimeout();
} else {
this.eventHandlers.onReceiveResponse(response);
}
this.K = setTimeout(function () {
_this3.timer_K();
}, Timers.TIMER_K);
break;
case C.STATUS_COMPLETED:
break;
}
}
}
}, {
key: "C",
get: function get() {
return C;
}
}]);
return NonInviteClientTransaction;
}(EventEmitter);
var InviteClientTransaction = /*#__PURE__*/function (_EventEmitter2) {
_inherits(InviteClientTransaction, _EventEmitter2);
var _super2 = _createSuper(InviteClientTransaction);
function InviteClientTransaction(ua, transport, request, eventHandlers) {
var _this4;
_classCallCheck(this, InviteClientTransaction);
_this4 = _super2.call(this);
_this4.type = C.INVITE_CLIENT;
_this4.id = "z9hG4bK".concat(Math.floor(Math.random() * 10000000));
_this4.ua = ua;
_this4.transport = transport;
_this4.request = request;
_this4.eventHandlers = eventHandlers;
request.transaction = _assertThisInitialized(_this4);
var via = "SIP/2.0/".concat(transport.via_transport);
via += " ".concat(ua.configuration.via_host, ";branch=").concat(_this4.id);
_this4.request.setHeader('via', via);
_this4.ua.newTransaction(_assertThisInitialized(_this4));
return _this4;
}
_createClass(InviteClientTransaction, [{
key: "stateChanged",
value: function stateChanged(state) {
this.state = state;
this.emit('stateChanged');
}
}, {
key: "send",
value: function send() {
var _this5 = this;
this.stateChanged(C.STATUS_CALLING);
this.B = setTimeout(function () {
_this5.timer_B();
}, Timers.TIMER_B);
if (!this.transport.send(this.request)) {
this.onTransportError();
}
}
}, {
key: "onTransportError",
value: function onTransportError() {
clearTimeout(this.B);
clearTimeout(this.D);
clearTimeout(this.M);
if (this.state !== C.STATUS_ACCEPTED) {
loggerict.debug("transport error occurred, deleting transaction ".concat(this.id));
this.eventHandlers.onTransportError();
}
this.stateChanged(C.STATUS_TERMINATED);
this.ua.destroyTransaction(this);
} // RFC 6026 7.2.
}, {
key: "timer_M",
value: function timer_M() {
loggerict.debug("Timer M expired for transaction ".concat(this.id));
if (this.state === C.STATUS_ACCEPTED) {
clearTimeout(this.B);
this.stateChanged(C.STATUS_TERMINATED);
this.ua.destroyTransaction(this);
}
} // RFC 3261 17.1.1.
}, {
key: "timer_B",
value: function timer_B() {
loggerict.debug("Timer B expired for transaction ".concat(this.id));
if (this.state === C.STATUS_CALLING) {
this.stateChanged(C.STATUS_TERMINATED);
this.ua.destroyTransaction(this);
this.eventHandlers.onRequestTimeout();
}
}
}, {
key: "timer_D",
value: function timer_D() {
loggerict.debug("Timer D expired for transaction ".concat(this.id));
clearTimeout(this.B);
this.stateChanged(C.STATUS_TERMINATED);
this.ua.destroyTransaction(this);
}
}, {
key: "sendACK",
value: function sendACK(response) {
var _this6 = this;
var ack = new SIPMessage.OutgoingRequest(SimpleSIP_C.ACK, this.request.ruri, this.ua, {
'route_set': this.request.getHeaders('route'),
'call_id': this.request.getHeader('call-id'),
'cseq': this.request.cseq
});
ack.setHeader('from', this.request.getHeader('from'));
ack.setHeader('via', this.request.getHeader('via'));
ack.setHeader('to', response.getHeader('to'));
this.D = setTimeout(function () {
_this6.timer_D();
}, Timers.TIMER_D);
this.transport.send(ack);
}
}, {
key: "cancel",
value: function cancel(reason) {
// Send only if a provisional response (>100) has been received.
if (this.state !== C.STATUS_PROCEEDING) {
return;
}
var cancel = new SIPMessage.OutgoingRequest(SimpleSIP_C.CANCEL, this.request.ruri, this.ua, {
'route_set': this.request.getHeaders('route'),
'call_id': this.request.getHeader('call-id'),
'cseq': this.request.cseq
});
cancel.setHeader('from', this.request.getHeader('from'));
cancel.setHeader('via', this.request.getHeader('via'));
cancel.setHeader('to', this.request.getHeader('to'));
if (reason) {
cancel.setHeader('reason', reason);
}
this.transport.send(cancel);
}
}, {
key: "receiveResponse",
value: function receiveResponse(response) {
var _this7 = this;
var status_code = response.status_code;
if (status_code >= 100 && status_code <= 199) {
switch (this.state) {
case C.STATUS_CALLING:
this.stateChanged(C.STATUS_PROCEEDING);
this.eventHandlers.onReceiveResponse(response);
break;
case C.STATUS_PROCEEDING:
this.eventHandlers.onReceiveResponse(response);
break;
}
} else if (status_code >= 200 && status_code <= 299) {
switch (this.state) {
case C.STATUS_CALLING:
case C.STATUS_PROCEEDING:
this.stateChanged(C.STATUS_ACCEPTED);
this.M = setTimeout(function () {
_this7.timer_M();
}, Timers.TIMER_M);
this.eventHandlers.onReceiveResponse(response);
break;
case C.STATUS_ACCEPTED:
this.eventHandlers.onReceiveResponse(response);
break;
}
} else if (status_code >= 300 && status_code <= 699) {
switch (this.state) {
case C.STATUS_CALLING:
case C.STATUS_PROCEEDING:
this.stateChanged(C.STATUS_COMPLETED);
this.sendACK(response);
this.eventHandlers.onReceiveResponse(response);
break;
case C.STATUS_COMPLETED:
this.sendACK(response);
break;
}
}
}
}, {
key: "C",
get: function get() {
return C;
}
}]);
return InviteClientTransaction;
}(EventEmitter);
var AckClientTransaction = /*#__PURE__*/function (_EventEmitter3) {
_inherits(AckClientTransaction, _EventEmitter3);
var _super3 = _createSuper(AckClientTransaction);
function AckClientTransaction(ua, transport, request, eventHandlers) {
var _this8;
_classCallCheck(this, AckClientTransaction);
_this8 = _super3.call(this);
_this8.id = "z9hG4bK".concat(Math.floor(Math.random() * 10000000));
_this8.transport = transport;
_this8.request = request;
_this8.eventHandlers = eventHandlers;
var via = "SIP/2.0/".concat(transport.via_transport);
via += " ".concat(ua.configuration.via_host, ";branch=").concat(_this8.id);
_this8.request.setHeader('via', via);
return _this8;
}
_createClass(AckClientTransaction, [{
key: "send",
value: function send() {
if (!this.transport.send(this.request)) {
this.onTransportError();
}
}
}, {
key: "onTransportError",
value: function onTransportError() {
loggeract.debug("transport error occurred for transaction ".concat(this.id));
this.eventHandlers.onTransportError();
}
}, {
key: "C",
get: function get() {
return C;
}
}]);
return AckClientTransaction;
}(EventEmitter);
var NonInviteServerTransaction = /*#__PURE__*/function (_EventEmitter4) {
_inherits(NonInviteServerTransaction, _EventEmitter4);
var _super4 = _createSuper(NonInviteServerTransaction);
function NonInviteServerTransaction(ua, transport, request) {
var _this9;
_classCallCheck(this, NonInviteServerTransaction);
_this9 = _super4.call(this);
_this9.type = C.NON_INVITE_SERVER;
_this9.id = request.via_branch;
_this9.ua = ua;
_this9.transport = transport;
_this9.request = request;
_this9.last_response = '';
request.server_transaction = _assertThisInitialized(_this9);
_this9.state = C.STATUS_TRYING;
ua.newTransaction(_assertThisInitialized(_this9));
return _this9;
}
_createClass(NonInviteServerTransaction, [{
key: "stateChanged",
value: function stateChanged(state) {
this.state = state;
this.emit('stateChanged');
}
}, {
key: "timer_J",
value: function timer_J() {
loggernist.debug("Timer J expired for transaction ".concat(this.id));
this.stateChanged(C.STATUS_TERMINATED);
this.ua.destroyTransaction(this);
}
}, {
key: "onTransportError",
value: function onTransportError() {
if (!this.transportError) {
this.transportError = true;
loggernist.debug("transport error occurred, deleting transaction ".concat(this.id));
clearTimeout(this.J);
this.stateChanged(C.STATUS_TERMINATED);
this.ua.destroyTransaction(this);
}
}
}, {
key: "receiveResponse",
value: function receiveResponse(status_code, response, onSuccess, onFailure) {
var _this10 = this;
if (status_code === 100) {
/* RFC 4320 4.1
* 'A SIP element MUST NOT
* send any provisional response with a
* Status-Code other than 100 to a non-INVITE request.'
*/
switch (this.state) {
case C.STATUS_TRYING:
this.stateChanged(C.STATUS_PROCEEDING);
if (!this.transport.send(response)) {
this.onTransportError();
}
break;
case C.STATUS_PROCEEDING:
this.last_response = response;
if (!this.transport.send(response)) {
this.onTransportError();
if (onFailure) {
onFailure();
}
} else if (onSuccess) {
onSuccess();
}
break;
}
} else if (status_code >= 200 && status_code <= 699) {
switch (this.state) {
case C.STATUS_TRYING:
case C.STATUS_PROCEEDING:
this.stateChanged(C.STATUS_COMPLETED);
this.last_response = response;
this.J = setTimeout(function () {
_this10.timer_J();
}, Timers.TIMER_J);
if (!this.transport.send(response)) {
this.onTransportError();
if (onFailure) {
onFailure();
}
} else if (onSuccess) {
onSuccess();
}
break;
case C.STATUS_COMPLETED:
break;
}
}
}
}, {
key: "C",
get: function get() {
return C;
}
}]);
return NonInviteServerTransaction;
}(EventEmitter);
var InviteServerTransaction = /*#__PURE__*/function (_EventEmitter5) {
_inherits(InviteServerTransaction, _EventEmitter5);
var _super5 = _createSuper(InviteServerTransaction);
function InviteServerTransaction(ua, transport, request) {
var _this11;
_classCallCheck(this, InviteServerTransaction);
_this11 = _super5.call(this);
_this11.type = C.INVITE_SERVER;
_this11.id = request.via_branch;
_this11.ua = ua;
_this11.transport = transport;
_this11.request = request;
_this11.last_response = '';
request.server_transaction = _assertThisInitialized(_this11);
_this11.state = C.STATUS_PROCEEDING;
ua.newTransaction(_assertThisInitialized(_this11));
_this11.resendProvisionalTimer = null;
request.reply(100);
return _this11;
}
_createClass(InviteServerTransaction, [{
key: "stateChanged",
value: function stateChanged(state) {
this.state = state;
this.emit('stateChanged');
}
}, {
key: "timer_H",
value: function timer_H() {
loggerist.debug("Timer H expired for transaction ".concat(this.id));
if (this.state === C.STATUS_COMPLETED) {
loggerist.debug('ACK not received, dialog will be terminated');
}
this.stateChanged(C.STATUS_TERMINATED);
this.ua.destroyTransaction(this);
}
}, {
key: "timer_I",
value: function timer_I() {
this.stateChanged(C.STATUS_TERMINATED);
this.ua.destroyTransaction(this);
} // RFC 6026 7.1.
}, {
key: "timer_L",
value: function timer_L() {
loggerist.debug("Timer L expired for transaction ".concat(this.id));
if (this.state === C.STATUS_ACCEPTED) {
this.stateChanged(C.STATUS_TERMINATED);
this.ua.destroyTransaction(this);
}
}
}, {
key: "onTransportError",
value: function onTransportError() {
if (!this.transportError) {
this.transportError = true;
loggerist.debug("transport error occurred, deleting transaction ".concat(this.id));
if (this.resendProvisionalTimer !== null) {
clearInterval(this.resendProvisionalTimer);
this.resendProvisionalTimer = null;
}
clearTimeout(this.L);
clearTimeout(this.H);
clearTimeout(this.I);
this.stateChanged(C.STATUS_TERMINATED);
this.ua.destroyTransaction(this);
}
}
}, {
key: "resend_provisional",
value: function resend_provisional() {
if (!this.transport.send(this.last_response)) {
this.onTransportError();
}
} // INVITE Server Transaction RFC 3261 17.2.1.
}, {
key: "receiveResponse",
value: function receiveResponse(status_code, response, onSuccess, onFailure) {
var _this12 = this;
if (status_code >= 100 && status_code <= 199) {
switch (this.state) {
case C.STATUS_PROCEEDING:
if (!this.transport.send(response)) {
this.onTransportError();
}
this.last_response = response;
break;
}
}
if (status_code > 100 && status_code <= 199 && this.state === C.STATUS_PROCEEDING) {
// Trigger the resendProvisionalTimer only for the first non 100 provisional response.
if (this.resendProvisionalTimer === null) {
this.resendProvisionalTimer = setInterval(function () {
_this12.resend_provisional();
}, Timers.PROVISIONAL_RESPONSE_INTERVAL);
}
} else if (status_code >= 200 && status_code <= 299) {
switch (this.state) {
case C.STATUS_PROCEEDING:
this.stateChanged(C.STATUS_ACCEPTED);
this.last_response = response;
this.L = setTimeout(function () {
_this12.timer_L();
}, Timers.TIMER_L);
if (this.resendProvisionalTimer !== null) {
clearInterval(this.resendProvisionalTimer);
this.resendProvisionalTimer = null;
}
/* falls through */
case C.STATUS_ACCEPTED:
// Note that this point will be reached for proceeding this.state also.
if (!this.transport.send(response)) {
this.onTransportError();
if (onFailure) {
onFailure();
}
} else if (onSuccess) {
onSuccess();
}
break;
}
} else if (status_code >= 300 && status_code <= 699) {
switch (this.state) {
case C.STATUS_PROCEEDING:
if (this.resendProvisionalTimer !== null) {
clearInterval(this.resendProvisionalTimer);
this.resendProvisionalTimer = null;
}
if (!this.transport.send(response)) {
this.onTransportError();
if (onFailure) {
onFailure();
}
} else {
this.stateChanged(C.STATUS_COMPLETED);
this.H = setTimeout(function () {
_this12.timer_H();
}, Timers.TIMER_H);
if (onSuccess) {
onSuccess();
}
}
break;
}
}
}
}, {
key: "C",
get: function get() {
return C;
}
}]);
return InviteServerTransaction;
}(EventEmitter);
/**
* INVITE:
* _true_ if retransmission
* _false_ new request
*
* ACK:
* _true_ ACK to non2xx response
* _false_ ACK must be passed to TU (accepted state)
* ACK to 2xx response
*
* CANCEL:
* _true_ no matching invite transaction
* _false_ matching invite transaction and no final response sent
*
* OTHER:
* _true_ retransmission
* _false_ new request
*/
function checkTransaction(_ref, request) {
var _transactions = _ref._transactions;
var tr;
switch (request.method) {
case SimpleSIP_C.INVITE:
tr = _transactions.ist[request.via_branch];
if (tr) {
switch (tr.state) {
case C.STATUS_PROCEEDING:
tr.transport.send(tr.last_response);
break;
// RFC 6026 7.1 Invite retransmission.
// Received while in C.STATUS_ACCEPTED state. Absorb it.
case C.STATUS_ACCEPTED:
break;
}
return true;
}
break;
case SimpleSIP_C.ACK:
tr = _transactions.ist[request.via_branch]; // RFC 6026 7.1.
if (tr) {
if (tr.state === C.STATUS_ACCEPTED) {
return false;
} else if (tr.state === C.STATUS_COMPLETED) {
tr.state = C.STATUS_CONFIRMED;
tr.I = setTimeout(function () {
tr.timer_I();
}, Timers.TIMER_I);
return true;
}
} // ACK to 2XX Response.
else {
return false;
}
break;
case SimpleSIP_C.CANCEL:
tr = _transactions.ist[request.via_branch];
if (tr) {
request.reply_sl(200);
if (tr.state === C.STATUS_PROCEEDING) {
return false;
} else {
return true;
}
} else {
request.reply_sl(481);
return true;
}
default:
// Non-INVITE Server Transaction RFC 3261 17.2.2.
tr = _transactions.nist[request.via_branch];
if (tr) {
switch (tr.state) {
case C.STATUS_TRYING:
break;
case C.STATUS_PROCEEDING:
case C.STATUS_COMPLETED:
tr.transport.send(tr.last_response);
break;
}
return true;
}
break;
}
}
module.exports = {
C: C,
NonInviteClientTransaction: NonInviteClientTransaction,
InviteClientTransaction: InviteClientTransaction,
AckClientTransaction: AckClientTransaction,
NonInviteServerTransaction: NonInviteServerTransaction,
InviteServerTransaction: InviteServerTransaction,
checkTransaction: checkTransaction
};
},{"./Constants":2,"./Logger":9,"./SIPMessage":21,"./Timers":23,"events":31}],25:[function(require,module,exports){
"use strict";
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }
var Logger = require('./Logger');
var Socket = require('./Socket');
var SimpleSIP_C = require('./Constants');
var logger = new Logger('Transport');
/**
* Constants
*/
var C = {
// Transport status.
STATUS_CONNECTED: 0,
STATUS_CONNECTING: 1,
STATUS_DISCONNECTED: 2,
// Socket status.
SOCKET_STATUS_READY: 0,
SOCKET_STATUS_ERROR: 1,
// Recovery options.
recovery_options: {
// minimum interval in seconds between recover attempts.
min_interval: SimpleSIP_C.CONNECTION_RECOVERY_MIN_INTERVAL,
// maximum interval in seconds between recover attempts.
max_interval: SimpleSIP_C.CONNECTION_RECOVERY_MAX_INTERVAL
}
};
/*
* Manages one or multiple SimpleSIP.Socket instances.
* Is reponsible for transport recovery logic among all socket instances.
*
* @socket SimpleSIP::Socket instance
*/
module.exports = /*#__PURE__*/function () {
function Transport(sockets) {
var recovery_options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : C.recovery_options;
_classCallCheck(this, Transport);
logger.debug('new()');
this.status = C.STATUS_DISCONNECTED; // Current socket.
this.socket = null; // Socket collection.
this.sockets = [];
this.recovery_options = recovery_options;
this.recover_attempts = 0;
this.recovery_timer = null;
this.close_requested = false; // It seems that TextDecoder is not available in some versions of React-Native.
// See https://github.com/versatica/SimpleSIP/issues/695
try {
this.textDecoder = new TextDecoder('utf8');
} catch (error) {
logger.warn("cannot use TextDecoder: ".concat(error));
}
if (typeof sockets === 'undefined') {
throw new TypeError('Invalid argument.' + ' undefined \'sockets\' argument');
}
if (!(sockets instanceof Array)) {
sockets = [sockets];
}
sockets.forEach(function (socket) {
if (!Socket.isSocket(socket.socket)) {
throw new TypeError('Invalid argument.' + ' invalid \'SimpleSIP.Socket\' instance');
}
if (socket.weight && !Number(socket.weight)) {
throw new TypeError('Invalid argument.' + ' \'weight\' attribute is not a number');
}
this.sockets.push({
socket: socket.socket,
weight: socket.weight || 0,
status: C.SOCKET_STATUS_READY
});
}, this); // Get the socket with higher weight.
this._getSocket();
}
/**
* Instance Methods
*/
_createClass(Transport, [{
key: "connect",
value: function connect() {
logger.debug('connect()');
if (this.isConnected()) {
logger.debug('Transport is already connected');
return;
} else if (this.isConnecting()) {
logger.debug('Transport is connecting');
return;
}
this.close_requested = false;
this.status = C.STATUS_CONNECTING;
this.onconnecting({
socket: this.socket,
attempts: this.recover_attempts
});
if (!this.close_requested) {
// Bind socket event callbacks.
this.socket.onconnect = this._onConnect.bind(this);
this.socket.ondisconnect = this._onDisconnect.bind(this);
this.socket.ondata = this._onData.bind(this);
this.socket.connect();
}
return;
}
}, {
key: "disconnect",
value: function disconnect() {
logger.debug('close()');
this.close_requested = true;
this.recover_attempts = 0;
this.status = C.STATUS_DISCONNECTED; // Clear recovery_timer.
if (this.recovery_timer !== null) {
clearTimeout(this.recovery_timer);
this.recovery_timer = null;
} // Unbind socket event callbacks.
this.socket.onconnect = function () {};
this.socket.ondisconnect = function () {};
this.socket.ondata = function () {};
this.socket.disconnect();
this.ondisconnect({
socket: this.socket,
error: false
});
}
}, {
key: "send",
value: function send(data) {
logger.debug('send()');
if (!this.isConnected()) {
logger.warn('unable to send message, transport is not connected');
return false;
}
var message = data.toString();
logger.debug("sending message:\n\n".concat(message, "\n"));
return this.socket.send(message);
}
}, {
key: "isConnected",
value: function isConnected() {
return this.status === C.STATUS_CONNECTED;
}
}, {
key: "isConnecting",
value: function isConnecting() {
return this.status === C.STATUS_CONNECTING;
}
/**
* Private API.
*/
}, {
key: "_reconnect",
value: function _reconnect() {
var _this = this;
this.recover_attempts += 1;
var k = Math.floor(Math.random() * Math.pow(2, this.recover_attempts) + 1);
if (k < this.recovery_options.min_interval) {
k = this.recovery_options.min_interval;
} else if (k > this.recovery_options.max_interval) {
k = this.recovery_options.max_interval;
}
logger.debug("reconnection attempt: ".concat(this.recover_attempts, ". next connection attempt in ").concat(k, " seconds"));
this.recovery_timer = setTimeout(function () {
if (!_this.close_requested && !(_this.isConnected() || _this.isConnecting())) {
// Get the next available socket with higher weight.
_this._getSocket(); // Connect the socket.
_this.connect();
}
}, k * 1000);
}
/**
* get the next available socket with higher weight
*/
}, {
key: "_getSocket",
value: function _getSocket() {
var candidates = [];
this.sockets.forEach(function (socket) {
if (socket.status === C.SOCKET_STATUS_ERROR) {
return; // continue the array iteration
} else if (candidates.length === 0) {
candidates.push(socket);
} else if (socket.weight > candidates[0].weight) {
candidates = [socket];
} else if (socket.weight === candidates[0].weight) {
candidates.push(socket);
}
});
if (candidates.length === 0) {
// All sockets have failed. reset sockets status.
this.sockets.forEach(function (socket) {
socket.status = C.SOCKET_STATUS_READY;
}); // Get next available socket.
this._getSocket();
return;
}
var idx = Math.floor(Math.random() * candidates.length);
this.socket = candidates[idx].socket;
}
/**
* Socket Event Handlers
*/
}, {
key: "_onConnect",
value: function _onConnect() {
this.recover_attempts = 0;
this.status = C.STATUS_CONNECTED; // Clear recovery_timer.
if (this.recovery_timer !== null) {
clearTimeout(this.recovery_timer);
this.recovery_timer = null;
}
this.onconnect({
socket: this
});
}
}, {
key: "_onDisconnect",
value: function _onDisconnect(error, code, reason) {
this.status = C.STATUS_DISCONNECTED;
this.ondisconnect({
socket: this.socket,
error: error,
code: code,
reason: reason
});
if (this.close_requested) {
return;
} // Update socket status.
else {
this.sockets.forEach(function (socket) {
if (this.socket === socket.socket) {
socket.status = C.SOCKET_STATUS_ERROR;
}
}, this);
}
this._reconnect(error);
}
}, {
key: "_onData",
value: function _onData(data) {
// CRLF Keep Alive request from server, reply.
if (data === '\r\n\r\n') {
logger.debug('received message with double-CRLF Keep Alive request');
try {
// Reply with single CRLF.
this.socket.send('\r\n');
} catch (error) {
logger.warn("error sending Keep Alive response: ".concat(error));
}
return;
} // CRLF Keep Alive response from server, ignore it.
if (data === '\r\n') {
logger.debug('received message with CRLF Keep Alive response');
return;
} // Binary message.
else if (typeof data !== 'string') {
try {
if (this.textDecoder) data = this.textDecoder.decode(data);else data = String.fromCharCode.apply(null, new Uint8Array(data));
} catch (evt) {
logger.debug('received binary message failed to be converted into string,' + ' message discarded');
return;
}
logger.debug("received binary message:\n\n".concat(data, "\n"));
} // Text message.
else {
logger.debug("received text message:\n\n".concat(data, "\n"));
}
this.ondata({
transport: this,
message: data
});
}
}, {
key: "via_transport",
get: function get() {
return this.socket.via_transport;
}
}, {
key: "url",
get: function get() {
return this.socket.url;
}
}, {
key: "sip_uri",
get: function get() {
return this.socket.sip_uri;
}
}]);
return Transport;
}();
},{"./Constants":2,"./Logger":9,"./Socket":22}],26:[function(require,module,exports){
"use strict";
function _typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); if (superClass) _setPrototypeOf(subClass, superClass); }
function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }
function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; }
function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === "object" || typeof call === "function")) { return call; } return _assertThisInitialized(self); }
function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; }
function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); return true; } catch (e) { return false; } }
function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }
var EventEmitter = require('events').EventEmitter;
var Logger = require('./Logger');
var SimpleSIP_C = require('./Constants');
var Registrator = require('./Registrator');
var RTCSession = require('./RTCSession');
var Message = require('./Message');
var Options = require('./Options');
var Transactions = require('./Transactions');
var Transport = require('./Transport');
var Utils = require('./Utils');
var Exceptions = require('./Exceptions');
var URI = require('./URI');
var Parser = require('./Parser');
var SIPMessage = require('./SIPMessage');
var sanityCheck = require('./sanityCheck');
var config = require('./Config');
var logger = new Logger('UA');
var C = {
// UA status codes.
STATUS_INIT: 0,
STATUS_READY: 1,
STATUS_USER_CLOSED: 2,
STATUS_NOT_READY: 3,
// UA error codes.
CONFIGURATION_ERROR: 1,
NETWORK_ERROR: 2
};
/**
* The User-Agent class.
* @class SimpleSIP.UA
* @param {Object} configuration Configuration parameters.
* @throws {SimpleSIP.Exceptions.ConfigurationError} If a configuration parameter is invalid.
* @throws {TypeError} If no configuration is given.
*/
module.exports = /*#__PURE__*/function (_EventEmitter) {
_inherits(UA, _EventEmitter);
var _super = _createSuper(UA);
_createClass(UA, null, [{
key: "C",
// Expose C object.
get: function get() {
return C;
}
}]);
function UA(configuration) {
var _this;
_classCallCheck(this, UA);
logger.debug('new() [configuration:%o]', configuration);
_this = _super.call(this);
_this._cache = {
credentials: {}
};
_this._configuration = Object.assign({}, config.settings);
_this._dynConfiguration = {};
_this._dialogs = {}; // User actions outside any session/dialog (MESSAGE/OPTIONS).
_this._applicants = {};
_this._sessions = {};
_this._transport = null;
_this._contact = null;
_this._status = C.STATUS_INIT;
_this._error = null;
_this._transactions = {
nist: {},
nict: {},
ist: {},
ict: {}
}; // Custom UA empty object for high level use.
_this._data = {};
_this._closeTimer = null; // Check configuration argument.
if (configuration === undefined) {
throw new TypeError('Not enough arguments');
} // Load configuration.
try {
_this._loadConfig(configuration);
} catch (e) {
_this._status = C.STATUS_NOT_READY;
_this._error = C.CONFIGURATION_ERROR;
throw e;
} // Initialize registrator.
_this._registrator = new Registrator(_assertThisInitialized(_this));
return _this;
}
_createClass(UA, [{
key: "start",
// =================
// High Level API
// =================
/**
* Connect to the server if status = STATUS_INIT.
* Resume UA after being closed.
*/
value: function start() {
logger.debug('start()');
if (this._status === C.STATUS_INIT) {
this._transport.connect();
} else if (this._status === C.STATUS_USER_CLOSED) {
logger.debug('restarting UA'); // Disconnect.
if (this._closeTimer !== null) {
clearTimeout(this._closeTimer);
this._closeTimer = null;
this._transport.disconnect();
} // Reconnect.
this._status = C.STATUS_INIT;
this._transport.connect();
} else if (this._status === C.STATUS_READY) {
logger.debug('UA is in READY status, not restarted');
} else {
logger.debug('ERROR: connection is down, Auto-Recovery system is trying to reconnect');
} // Set dynamic configuration.
this._dynConfiguration.register = this._configuration.register;
}
/**
* Register.
*/
}, {
key: "register",
value: function register() {
logger.debug('register()');
this._dynConfiguration.register = true;
this._registrator.register();
}
/**
* Unregister.
*/
}, {
key: "unregister",
value: function unregister(options) {
logger.debug('unregister()');
this._dynConfiguration.register = false;
this._registrator.unregister(options);
}
/**
* Get the Registrator instance.
*/
}, {
key: "registrator",
value: function registrator() {
return this._registrator;
}
/**
* Registration state.
*/
}, {
key: "isRegistered",
value: function isRegistered() {
return this._registrator.registered;
}
/**
* Connection state.
*/
}, {
key: "isConnected",
value: function isConnected() {
return this._transport.isConnected();
}
/**
* Make an outgoing call.
*
* -param {String} target
* -param {Object} [options]
*
* -throws {TypeError}
*
*/
}, {
key: "call",
value: function call(target, options) {
logger.debug('call()');
var session = new RTCSession(this);
session.connect(target, options);
return session;
}
/**
* Send a message.
*
* -param {String} target
* -param {String} body
* -param {Object} [options]
*
* -throws {TypeError}
*
*/
}, {
key: "sendMessage",
value: function sendMessage(target, body, options) {
logger.debug('sendMessage()');
var message = new Message(this);
message.send(target, body, options);
return message;
}
/**
* Send a SIP OPTIONS.
*
* -param {String} target
* -param {String} [body]
* -param {Object} [options]
*
* -throws {TypeError}
*
*/
}, {
key: "sendOptions",
value: function sendOptions(target, body, options) {
logger.debug('sendOptions()');
var message = new Options(this);
message.send(target, body, options);
return message;
}
/**
* Terminate ongoing sessions.
*/
}, {
key: "terminateSessions",
value: function terminateSessions(options) {
logger.debug('terminateSessions()');
for (var idx in this._sessions) {
if (!this._sessions[idx].isEnded()) {
this._sessions[idx].terminate(options);
}
}
}
/**
* Gracefully close.
*
*/
}, {
key: "stop",
value: function stop() {
var _this2 = this;
logger.debug('stop()'); // Remove dynamic settings.
this._dynConfiguration = {};
if (this._status === C.STATUS_USER_CLOSED) {
logger.debug('UA already closed');
return;
} // Close registrator.
this._registrator.close(); // If there are session wait a bit so CANCEL/BYE can be sent and their responses received.
var num_sessions = Object.keys(this._sessions).length; // Run _terminate_ on every Session.
for (var session in this._sessions) {
if (Object.prototype.hasOwnProperty.call(this._sessions, session)) {
logger.debug("closing session ".concat(session));
try {
this._sessions[session].terminate();
} catch (error) {}
}
} // Run _close_ on every applicant.
for (var applicant in this._applicants) {
if (Object.prototype.hasOwnProperty.call(this._applicants, applicant)) try {
this._applicants[applicant].close();
} catch (error) {}
}
this._status = C.STATUS_USER_CLOSED;
var num_transactions = Object.keys(this._transactions.nict).length + Object.keys(this._transactions.nist).length + Object.keys(this._transactions.ict).length + Object.keys(this._transactions.ist).length;
if (num_transactions === 0 && num_sessions === 0) {
this._transport.disconnect();
} else {
this._closeTimer = setTimeout(function () {
_this2._closeTimer = null;
_this2._transport.disconnect();
}, 2000);
}
}
/**
* Normalice a string into a valid SIP request URI
* -param {String} target
* -returns {SimpleSIP.URI|undefined}
*/
}, {
key: "normalizeTarget",
value: function normalizeTarget(target) {
return Utils.normalizeTarget(target, this._configuration.hostport_params);
}
/**
* Allow retrieving configuration and autogenerated fields in runtime.
*/
}, {
key: "get",
value: function get(parameter) {
switch (parameter) {
case 'authorization_user':
return this._configuration.authorization_user;
case 'realm':
return this._configuration.realm;
case 'ha1':
return this._configuration.ha1;
case 'authorization_jwt':
return this._configuration.authorization_jwt;
default:
logger.warn('get() | cannot get "%s" parameter in runtime', parameter);
return undefined;
}
}
/**
* Allow configuration changes in runtime.
* Returns true if the parameter could be set.
*/
}, {
key: "set",
value: function set(parameter, value) {
switch (parameter) {
case 'authorization_user':
{
this._configuration.authorization_user = String(value);
break;
}
case 'password':
{
this._configuration.password = String(value);
break;
}
case 'realm':
{
this._configuration.realm = String(value);
break;
}
case 'ha1':
{
this._configuration.ha1 = String(value); // Delete the plain SIP password.
this._configuration.password = null;
break;
}
case 'authorization_jwt':
{
this._configuration.authorization_jwt = String(value);
break;
}
case 'display_name':
{
this._configuration.display_name = value;
break;
}
case 'extra_headers':
{
this._configuration.extra_headers = value;
break;
}
default:
logger.warn('set() | cannot set "%s" parameter in runtime', parameter);
return false;
}
return true;
} // ==========================
// Event Handlers.
// ==========================
/**
* new Transaction
*/
}, {
key: "newTransaction",
value: function newTransaction(transaction) {
this._transactions[transaction.type][transaction.id] = transaction;
this.emit('newTransaction', {
transaction: transaction
});
}
/**
* Transaction destroyed.
*/
}, {
key: "destroyTransaction",
value: function destroyTransaction(transaction) {
delete this._transactions[transaction.type][transaction.id];
this.emit('transactionDestroyed', {
transaction: transaction
});
}
/**
* new Dialog
*/
}, {
key: "newDialog",
value: function newDialog(dialog) {
this._dialogs[dialog.id] = dialog;
}
/**
* Dialog destroyed.
*/
}, {
key: "destroyDialog",
value: function destroyDialog(dialog) {
delete this._dialogs[dialog.id];
}
/**
* new Message
*/
}, {
key: "newMessage",
value: function newMessage(message, data) {
this._applicants[message] = message;
this.emit('newMessage', data);
}
/**
* new Options
*/
}, {
key: "newOptions",
value: function newOptions(message, data) {
this._applicants[message] = message;
this.emit('newOptions', data);
}
/**
* Message destroyed.
*/
}, {
key: "destroyMessage",
value: function destroyMessage(message) {
delete this._applicants[message];
}
/**
* new RTCSession
*/
}, {
key: "newRTCSession",
value: function newRTCSession(session, data) {
this._sessions[session.id] = session;
this.emit('newRTCSession', data);
}
/**
* RTCSession destroyed.
*/
}, {
key: "destroyRTCSession",
value: function destroyRTCSession(session) {
delete this._sessions[session.id];
}
/**
* Registered
*/
}, {
key: "registered",
value: function registered(data) {
this.emit('registered', data);
}
/**
* Unregistered
*/
}, {
key: "unregistered",
value: function unregistered(data) {
this.emit('unregistered', data);
}
/**
* Registration Failed
*/
}, {
key: "registrationFailed",
value: function registrationFailed(data) {
this.emit('registrationFailed', data);
} // =========================
// ReceiveRequest.
// =========================
/**
* Request reception
*/
}, {
key: "receiveRequest",
value: function receiveRequest(request) {
var method = request.method; // Check that request URI points to us.
if (request.ruri.user !== this._configuration.uri.user && request.ruri.user !== this._contact.uri.user) {
logger.debug('Request-URI does not point to us');
if (request.method !== SimpleSIP_C.ACK) {
request.reply_sl(404);
}
return;
} // Check request URI scheme.
if (request.ruri.scheme === SimpleSIP_C.SIPS) {
request.reply_sl(416);
return;
} // Check transaction.
if (Transactions.checkTransaction(this, request)) {
return;
} // Create the server transaction.
if (method === SimpleSIP_C.INVITE) {
/* eslint-disable no-new */
new Transactions.InviteServerTransaction(this, this._transport, request);
/* eslint-enable no-new */
} else if (method !== SimpleSIP_C.ACK && method !== SimpleSIP_C.CANCEL) {
/* eslint-disable no-new */
new Transactions.NonInviteServerTransaction(this, this._transport, request);
/* eslint-enable no-new */
}
/* RFC3261 12.2.2
* Requests that do not change in any way the state of a dialog may be
* received within a dialog (for example, an OPTIONS request).
* They are processed as if they had been received outside the dialog.
*/
if (method === SimpleSIP_C.OPTIONS) {
if (this.listeners('newOptions').length === 0) {
request.reply(200);
return;
}
var message = new Options(this);
message.init_incoming(request);
} else if (method === SimpleSIP_C.MESSAGE) {
if (this.listeners('newMessage').length === 0) {
request.reply(405);
return;
}
var _message = new Message(this);
_message.init_incoming(request);
} else if (method === SimpleSIP_C.INVITE) {
// Initial INVITE.
if (!request.to_tag && this.listeners('newRTCSession').length === 0) {
request.reply(405);
return;
}
}
var dialog;
var session; // Initial Request.
if (!request.to_tag) {
switch (method) {
case SimpleSIP_C.INVITE:
if (window.RTCPeerConnection) {
// TODO
if (request.hasHeader('replaces')) {
var replaces = request.replaces;
dialog = this._findDialog(replaces.call_id, replaces.from_tag, replaces.to_tag);
if (dialog) {
session = dialog.owner;
if (!session.isEnded()) {
session.receiveRequest(request);
} else {
request.reply(603);
}
} else {
request.reply(481);
}
} else {
session = new RTCSession(this);
session.init_incoming(request);
}
} else {
logger.warn('INVITE received but WebRTC is not supported');
request.reply(488);
}
break;
case SimpleSIP_C.BYE:
// Out of dialog BYE received.
request.reply(481);
break;
case SimpleSIP_C.CANCEL:
session = this._findSession(request);
if (session) {
session.receiveRequest(request);
} else {
logger.debug('received CANCEL request for a non existent session');
}
break;
case SimpleSIP_C.ACK:
/* Absorb it.
* ACK request without a corresponding Invite Transaction
* and without To tag.
*/
break;
case SimpleSIP_C.NOTIFY:
// Receive new sip event.
this.emit('sipEvent', {
event: request.event,
request: request
});
request.reply(200);
break;
default:
request.reply(405);
break;
}
} // In-dialog request.
else {
dialog = this._findDialog(request.call_id, request.from_tag, request.to_tag);
if (dialog) {
dialog.receiveRequest(request);
} else if (method === SimpleSIP_C.NOTIFY) {
session = this._findSession(request);
if (session) {
session.receiveRequest(request);
} else {
logger.debug('received NOTIFY request for a non existent subscription');
request.reply(481, 'Subscription does not exist');
}
}
/* RFC3261 12.2.2
* Request with to tag, but no matching dialog found.
* Exception: ACK for an Invite request for which a dialog has not
* been created.
*/
else if (method !== SimpleSIP_C.ACK) {
request.reply(481);
}
}
} // =================
// Utils.
// =================
/**
* Get the session to which the request belongs to, if any.
*/
}, {
key: "_findSession",
value: function _findSession(_ref) {
var call_id = _ref.call_id,
from_tag = _ref.from_tag,
to_tag = _ref.to_tag;
var sessionIDa = call_id + from_tag;
var sessionA = this._sessions[sessionIDa];
var sessionIDb = call_id + to_tag;
var sessionB = this._sessions[sessionIDb];
if (sessionA) {
return sessionA;
} else if (sessionB) {
return sessionB;
} else {
return null;
}
}
/**
* Get the dialog to which the request belongs to, if any.
*/
}, {
key: "_findDialog",
value: function _findDialog(call_id, from_tag, to_tag) {
var id = call_id + from_tag + to_tag;
var dialog = this._dialogs[id];
if (dialog) {
return dialog;
} else {
id = call_id + to_tag + from_tag;
dialog = this._dialogs[id];
if (dialog) {
return dialog;
} else {
return null;
}
}
}
}, {
key: "_loadConfig",
value: function _loadConfig(configuration) {
// Check and load the given configuration.
try {
config.load(this._configuration, configuration);
} catch (e) {
throw e;
} // Post Configuration Process.
// Allow passing 0 number as display_name.
if (this._configuration.display_name === 0) {
this._configuration.display_name = '0';
} // Instance-id for GRUU.
if (!this._configuration.instance_id) {
this._configuration.instance_id = Utils.newUUID();
} // SimpleSIP_id instance parameter. Static random tag of length 5.
this._configuration.SimpleSIP_id = Utils.createRandomToken(5); // String containing this._configuration.uri without scheme and user.
var hostport_params = this._configuration.uri.clone();
hostport_params.user = null;
this._configuration.hostport_params = hostport_params.toString().replace(/^sip:/i, ''); // Transport.
try {
this._transport = new Transport(this._configuration.sockets, {
// Recovery options.
max_interval: this._configuration.connection_recovery_max_interval,
min_interval: this._configuration.connection_recovery_min_interval
}); // Transport event callbacks.
this._transport.onconnecting = onTransportConnecting.bind(this);
this._transport.onconnect = onTransportConnect.bind(this);
this._transport.ondisconnect = onTransportDisconnect.bind(this);
this._transport.ondata = onTransportData.bind(this);
} catch (e) {
logger.warn(e);
throw new Exceptions.ConfigurationError('sockets', this._configuration.sockets);
} // Remove sockets instance from configuration object.
delete this._configuration.sockets; // Check whether authorization_user is explicitly defined.
// Take 'this._configuration.uri.user' value if not.
if (!this._configuration.authorization_user) {
this._configuration.authorization_user = this._configuration.uri.user;
} // If no 'registrar_server' is set use the 'uri' value without user portion and
// without URI params/headers.
if (!this._configuration.registrar_server) {
var registrar_server = this._configuration.uri.clone();
registrar_server.user = null;
registrar_server.clearParams();
registrar_server.clearHeaders();
this._configuration.registrar_server = registrar_server;
} // User no_answer_timeout.
this._configuration.no_answer_timeout *= 1000; // Via Host.
if (this._configuration.contact_uri) {
this._configuration.via_host = this._configuration.contact_uri.host;
} // Contact URI.
else {
this._configuration.contact_uri = new URI('sip', Utils.createRandomToken(8), this._configuration.via_host, null, {
transport: 'ws'
});
}
this._contact = {
pub_gruu: null,
temp_gruu: null,
uri: this._configuration.contact_uri,
toString: function toString() {
var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
var anonymous = options.anonymous || null;
var outbound = options.outbound || null;
var contact = '<';
if (anonymous) {
contact += this.temp_gruu || 'sip:anonymous@anonymous.invalid;transport=ws';
} else {
contact += this.pub_gruu || this.uri.toString();
}
if (outbound && (anonymous ? !this.temp_gruu : !this.pub_gruu)) {
contact += ';ob';
}
contact += '>';
return contact;
}
}; // Seal the configuration.
var writable_parameters = ['authorization_user', 'password', 'realm', 'ha1', 'authorization_jwt', 'display_name', 'register', 'extra_headers'];
for (var parameter in this._configuration) {
if (Object.prototype.hasOwnProperty.call(this._configuration, parameter)) {
if (writable_parameters.indexOf(parameter) !== -1) {
Object.defineProperty(this._configuration, parameter, {
writable: true,
configurable: false
});
} else {
Object.defineProperty(this._configuration, parameter, {
writable: false,
configurable: false
});
}
}
}
logger.debug('configuration parameters after validation:');
for (var _parameter in this._configuration) {
// Only show the user user configurable parameters.
if (Object.prototype.hasOwnProperty.call(config.settings, _parameter)) {
switch (_parameter) {
case 'uri':
case 'registrar_server':
logger.debug("- ".concat(_parameter, ": ").concat(this._configuration[_parameter]));
break;
case 'password':
case 'ha1':
case 'authorization_jwt':
logger.debug("- ".concat(_parameter, ": NOT SHOWN"));
break;
default:
logger.debug("- ".concat(_parameter, ": ").concat(JSON.stringify(this._configuration[_parameter])));
}
}
}
return;
}
}, {
key: "C",
get: function get() {
return C;
}
}, {
key: "status",
get: function get() {
return this._status;
}
}, {
key: "contact",
get: function get() {
return this._contact;
}
}, {
key: "configuration",
get: function get() {
return this._configuration;
}
}, {
key: "transport",
get: function get() {
return this._transport;
}
}]);
return UA;
}(EventEmitter);
/**
* Transport event handlers
*/
// Transport connecting event.
function onTransportConnecting(data) {
this.emit('connecting', data);
} // Transport connected event.
function onTransportConnect(data) {
if (this._status === C.STATUS_USER_CLOSED) {
return;
}
this._status = C.STATUS_READY;
this._error = null;
this.emit('connected', data);
if (this._dynConfiguration.register) {
this._registrator.register();
}
} // Transport disconnected event.
function onTransportDisconnect(data) {
// Run _onTransportError_ callback on every client transaction using _transport_.
var client_transactions = ['nict', 'ict', 'nist', 'ist'];
for (var _i = 0, _client_transactions = client_transactions; _i < _client_transactions.length; _i++) {
var type = _client_transactions[_i];
for (var id in this._transactions[type]) {
if (Object.prototype.hasOwnProperty.call(this._transactions[type], id)) {
this._transactions[type][id].onTransportError();
}
}
}
this.emit('disconnected', data); // Call registrator _onTransportClosed_.
this._registrator.onTransportClosed();
if (this._status !== C.STATUS_USER_CLOSED) {
this._status = C.STATUS_NOT_READY;
this._error = C.NETWORK_ERROR;
}
} // Transport data event.
function onTransportData(data) {
var transport = data.transport;
var message = data.message;
message = Parser.parseMessage(message, this);
if (!message) {
return;
}
if (this._status === C.STATUS_USER_CLOSED && message instanceof SIPMessage.IncomingRequest) {
return;
} // Do some sanity check.
if (!sanityCheck(message, this, transport)) {
return;
}
if (message instanceof SIPMessage.IncomingRequest) {
message.transport = transport;
this.receiveRequest(message);
} else if (message instanceof SIPMessage.IncomingResponse) {
/* Unike stated in 18.1.2, if a response does not match
* any transaction, it is discarded here and no passed to the core
* in order to be discarded there.
*/
var transaction;
switch (message.method) {
case SimpleSIP_C.INVITE:
transaction = this._transactions.ict[message.via_branch];
if (transaction) {
transaction.receiveResponse(message);
}
break;
case SimpleSIP_C.ACK:
// Just in case ;-).
break;
default:
transaction = this._transactions.nict[message.via_branch];
if (transaction) {
transaction.receiveResponse(message);
}
break;
}
}
}
},{"./Config":1,"./Constants":2,"./Exceptions":6,"./Logger":9,"./Message":10,"./Options":12,"./Parser":13,"./RTCSession":14,"./Registrator":19,"./SIPMessage":21,"./Transactions":24,"./Transport":25,"./URI":27,"./Utils":28,"./sanityCheck":30,"events":31}],27:[function(require,module,exports){
"use strict";
function _createForOfIteratorHelper(o, allowArrayLike) { var it; if (typeof Symbol === "undefined" || o[Symbol.iterator] == null) { if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = o[Symbol.iterator](); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it["return"] != null) it["return"](); } finally { if (didErr) throw err; } } }; }
function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }
var SimpleSIP_C = require('./Constants');
var Utils = require('./Utils');
var Grammar = require('./Grammar');
/**
* -param {String} [scheme]
* -param {String} [user]
* -param {String} host
* -param {String} [port]
* -param {Object} [parameters]
* -param {Object} [headers]
*
*/
module.exports = /*#__PURE__*/function () {
_createClass(URI, null, [{
key: "parse",
/**
* Parse the given string and returns a SimpleSIP.URI instance or undefined if
* it is an invalid URI.
*/
value: function parse(uri) {
uri = Grammar.parse(uri, 'SIP_URI');
if (uri !== -1) {
return uri;
} else {
return undefined;
}
}
}]);
function URI(scheme, user, host, port) {
var parameters = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : {};
var headers = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : {};
_classCallCheck(this, URI);
// Checks.
if (!host) {
throw new TypeError('missing or invalid "host" parameter');
} // Initialize parameters.
this._parameters = {};
this._headers = {};
this._scheme = scheme || SimpleSIP_C.SIP;
this._user = user;
this._host = host;
this._port = port;
for (var param in parameters) {
if (Object.prototype.hasOwnProperty.call(parameters, param)) {
this.setParam(param, parameters[param]);
}
}
for (var header in headers) {
if (Object.prototype.hasOwnProperty.call(headers, header)) {
this.setHeader(header, headers[header]);
}
}
}
_createClass(URI, [{
key: "setParam",
value: function setParam(key, value) {
if (key) {
this._parameters[key.toLowerCase()] = typeof value === 'undefined' || value === null ? null : value.toString();
}
}
}, {
key: "getParam",
value: function getParam(key) {
if (key) {
return this._parameters[key.toLowerCase()];
}
}
}, {
key: "hasParam",
value: function hasParam(key) {
if (key) {
return this._parameters.hasOwnProperty(key.toLowerCase()) && true || false;
}
}
}, {
key: "deleteParam",
value: function deleteParam(parameter) {
parameter = parameter.toLowerCase();
if (this._parameters.hasOwnProperty(parameter)) {
var value = this._parameters[parameter];
delete this._parameters[parameter];
return value;
}
}
}, {
key: "clearParams",
value: function clearParams() {
this._parameters = {};
}
}, {
key: "setHeader",
value: function setHeader(name, value) {
this._headers[Utils.headerize(name)] = Array.isArray(value) ? value : [value];
}
}, {
key: "getHeader",
value: function getHeader(name) {
if (name) {
return this._headers[Utils.headerize(name)];
}
}
}, {
key: "hasHeader",
value: function hasHeader(name) {
if (name) {
return this._headers.hasOwnProperty(Utils.headerize(name)) && true || false;
}
}
}, {
key: "deleteHeader",
value: function deleteHeader(header) {
header = Utils.headerize(header);
if (this._headers.hasOwnProperty(header)) {
var value = this._headers[header];
delete this._headers[header];
return value;
}
}
}, {
key: "clearHeaders",
value: function clearHeaders() {
this._headers = {};
}
}, {
key: "clone",
value: function clone() {
return new URI(this._scheme, this._user, this._host, this._port, JSON.parse(JSON.stringify(this._parameters)), JSON.parse(JSON.stringify(this._headers)));
}
}, {
key: "toString",
value: function toString() {
var headers = [];
var uri = "".concat(this._scheme, ":");
if (this._user) {
uri += "".concat(Utils.escapeUser(this._user), "@");
}
uri += this._host;
if (this._port || this._port === 0) {
uri += ":".concat(this._port);
}
for (var parameter in this._parameters) {
if (Object.prototype.hasOwnProperty.call(this._parameters, parameter)) {
uri += ";".concat(parameter);
if (this._parameters[parameter] !== null) {
uri += "=".concat(this._parameters[parameter]);
}
}
}
for (var header in this._headers) {
if (Object.prototype.hasOwnProperty.call(this._headers, header)) {
var _iterator = _createForOfIteratorHelper(this._headers[header]),
_step;
try {
for (_iterator.s(); !(_step = _iterator.n()).done;) {
var item = _step.value;
headers.push("".concat(header, "=").concat(item));
}
} catch (err) {
_iterator.e(err);
} finally {
_iterator.f();
}
}
}
if (headers.length > 0) {
uri += "?".concat(headers.join('&'));
}
return uri;
}
}, {
key: "toAor",
value: function toAor(show_port) {
var aor = "".concat(this._scheme, ":");
if (this._user) {
aor += "".concat(Utils.escapeUser(this._user), "@");
}
aor += this._host;
if (show_port && (this._port || this._port === 0)) {
aor += ":".concat(this._port);
}
return aor;
}
}, {
key: "scheme",
get: function get() {
return this._scheme;
},
set: function set(value) {
this._scheme = value.toLowerCase();
}
}, {
key: "user",
get: function get() {
return this._user;
},
set: function set(value) {
this._user = value;
}
}, {
key: "host",
get: function get() {
return this._host;
},
set: function set(value) {
this._host = value.toLowerCase();
}
}, {
key: "port",
get: function get() {
return this._port;
},
set: function set(value) {
this._port = value === 0 ? value : parseInt(value, 10) || null;
}
}]);
return URI;
}();
},{"./Constants":2,"./Grammar":7,"./Utils":28}],28:[function(require,module,exports){
"use strict";
function _typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }
function _createForOfIteratorHelper(o, allowArrayLike) { var it; if (typeof Symbol === "undefined" || o[Symbol.iterator] == null) { if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = o[Symbol.iterator](); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it["return"] != null) it["return"](); } finally { if (didErr) throw err; } } }; }
function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }
var SimpleSIP_C = require('./Constants');
var URI = require('./URI');
var Grammar = require('./Grammar');
exports.str_utf8_length = function (string) {
return unescape(encodeURIComponent(string)).length;
}; // Used by 'hasMethods'.
var isFunction = exports.isFunction = function (fn) {
if (fn !== undefined) {
return Object.prototype.toString.call(fn) === '[object Function]' ? true : false;
} else {
return false;
}
};
exports.isString = function (str) {
if (str !== undefined) {
return Object.prototype.toString.call(str) === '[object String]' ? true : false;
} else {
return false;
}
};
exports.isDecimal = function (num) {
return !isNaN(num) && parseFloat(num) === parseInt(num, 10);
};
exports.isEmpty = function (value) {
return value === null || value === '' || value === undefined || Array.isArray(value) && value.length === 0 || typeof value === 'number' && isNaN(value);
};
exports.hasMethods = function (obj) {
for (var _len = arguments.length, methodNames = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
methodNames[_key - 1] = arguments[_key];
}
for (var _i = 0, _methodNames = methodNames; _i < _methodNames.length; _i++) {
var methodName = _methodNames[_i];
if (isFunction(obj[methodName])) {
return false;
}
}
return true;
}; // Used by 'newTag'.
var createRandomToken = exports.createRandomToken = function (size) {
var base = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 32;
var i,
r,
token = '';
for (i = 0; i < size; i++) {
r = Math.random() * base | 0;
token += r.toString(base);
}
return token;
};
exports.newTag = function () {
return createRandomToken(10);
}; // https://stackoverflow.com/users/109538/broofa.
exports.newUUID = function () {
var UUID = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
var r = Math.random() * 16 | 0,
v = c === 'x' ? r : r & 0x3 | 0x8;
return v.toString(16);
});
return UUID;
};
exports.hostType = function (host) {
if (!host) {
return;
} else {
host = Grammar.parse(host, 'host');
if (host !== -1) {
return host.host_type;
}
}
};
/**
* Hex-escape a SIP URI user.
* Don't hex-escape ':' (%3A), '+' (%2B), '?' (%3F"), '/' (%2F).
*
* Used by 'normalizeTarget'.
*/
var escapeUser = exports.escapeUser = function (user) {
return encodeURIComponent(decodeURIComponent(user)).replace(/%3A/ig, ':').replace(/%2B/ig, '+').replace(/%3F/ig, '?').replace(/%2F/ig, '/');
};
/**
* Normalize SIP URI.
* NOTE: It does not allow a SIP URI without username.
* Accepts 'sip', 'sips' and 'tel' URIs and convert them into 'sip'.
* Detects the domain part (if given) and properly hex-escapes the user portion.
* If the user portion has only 'tel' number symbols the user portion is clean of 'tel' visual separators.
*/
exports.normalizeTarget = function (target, domain) {
// If no target is given then raise an error.
if (!target) {
return; // If a URI instance is given then return it.
} else if (target instanceof URI) {
return target; // If a string is given split it by '@':
// - Last fragment is the desired domain.
// - Otherwise append the given domain argument.
} else if (typeof target === 'string') {
var target_array = target.split('@');
var target_user;
var target_domain;
switch (target_array.length) {
case 1:
if (!domain) {
return;
}
target_user = target;
target_domain = domain;
break;
case 2:
target_user = target_array[0];
target_domain = target_array[1];
break;
default:
target_user = target_array.slice(0, target_array.length - 1).join('@');
target_domain = target_array[target_array.length - 1];
} // Remove the URI scheme (if present).
target_user = target_user.replace(/^(sips?|tel):/i, ''); // Remove 'tel' visual separators if the user portion just contains 'tel' number symbols.
if (/^[-.()]*\+?[0-9\-.()]+$/.test(target_user)) {
target_user = target_user.replace(/[-.()]/g, '');
} // Build the complete SIP URI.
target = "".concat(SimpleSIP_C.SIP, ":").concat(escapeUser(target_user), "@").concat(target_domain); // Finally parse the resulting URI.
var uri;
if (uri = URI.parse(target)) {
return uri;
} else {
return;
}
} else {
return;
}
};
exports.headerize = function (string) {
var exceptions = {
'Call-Id': 'Call-ID',
'Cseq': 'CSeq',
'Www-Authenticate': 'WWW-Authenticate'
};
var name = string.toLowerCase().replace(/_/g, '-').split('-');
var hname = '';
var parts = name.length;
var part;
for (part = 0; part < parts; part++) {
if (part !== 0) {
hname += '-';
}
hname += name[part].charAt(0).toUpperCase() + name[part].substring(1);
}
if (exceptions[hname]) {
hname = exceptions[hname];
}
return hname;
};
exports.sipErrorCause = function (status_code) {
for (var cause in SimpleSIP_C.SIP_ERROR_CAUSES) {
if (SimpleSIP_C.SIP_ERROR_CAUSES[cause].indexOf(status_code) !== -1) {
return SimpleSIP_C.causes[cause];
}
}
return SimpleSIP_C.causes.SIP_FAILURE_CODE;
};
/**
* Generate a random Test-Net IP (https://tools.ietf.org/html/rfc5735)
*/
exports.getRandomTestNetIP = function () {
function getOctet(from, to) {
return Math.floor(Math.random() * (to - from + 1) + from);
}
return "192.0.2.".concat(getOctet(1, 254));
}; // MD5 (Message-Digest Algorithm) https://www.webtoolkit.info.
exports.calculateMD5 = function (string) {
function rotateLeft(lValue, iShiftBits) {
return lValue << iShiftBits | lValue >>> 32 - iShiftBits;
}
function addUnsigned(lX, lY) {
var lX8 = lX & 0x80000000;
var lY8 = lY & 0x80000000;
var lX4 = lX & 0x40000000;
var lY4 = lY & 0x40000000;
var lResult = (lX & 0x3FFFFFFF) + (lY & 0x3FFFFFFF);
if (lX4 & lY4) {
return lResult ^ 0x80000000 ^ lX8 ^ lY8;
}
if (lX4 | lY4) {
if (lResult & 0x40000000) {
return lResult ^ 0xC0000000 ^ lX8 ^ lY8;
} else {
return lResult ^ 0x40000000 ^ lX8 ^ lY8;
}
} else {
return lResult ^ lX8 ^ lY8;
}
}
function doF(x, y, z) {
return x & y | ~x & z;
}
function doG(x, y, z) {
return x & z | y & ~z;
}
function doH(x, y, z) {
return x ^ y ^ z;
}
function doI(x, y, z) {
return y ^ (x | ~z);
}
function doFF(a, b, c, d, x, s, ac) {
a = addUnsigned(a, addUnsigned(addUnsigned(doF(b, c, d), x), ac));
return addUnsigned(rotateLeft(a, s), b);
}
function doGG(a, b, c, d, x, s, ac) {
a = addUnsigned(a, addUnsigned(addUnsigned(doG(b, c, d), x), ac));
return addUnsigned(rotateLeft(a, s), b);
}
function doHH(a, b, c, d, x, s, ac) {
a = addUnsigned(a, addUnsigned(addUnsigned(doH(b, c, d), x), ac));
return addUnsigned(rotateLeft(a, s), b);
}
function doII(a, b, c, d, x, s, ac) {
a = addUnsigned(a, addUnsigned(addUnsigned(doI(b, c, d), x), ac));
return addUnsigned(rotateLeft(a, s), b);
}
function convertToWordArray(str) {
var lWordCount;
var lMessageLength = str.length;
var lNumberOfWords_temp1 = lMessageLength + 8;
var lNumberOfWords_temp2 = (lNumberOfWords_temp1 - lNumberOfWords_temp1 % 64) / 64;
var lNumberOfWords = (lNumberOfWords_temp2 + 1) * 16;
var lWordArray = new Array(lNumberOfWords - 1);
var lBytePosition = 0;
var lByteCount = 0;
while (lByteCount < lMessageLength) {
lWordCount = (lByteCount - lByteCount % 4) / 4;
lBytePosition = lByteCount % 4 * 8;
lWordArray[lWordCount] = lWordArray[lWordCount] | str.charCodeAt(lByteCount) << lBytePosition;
lByteCount++;
}
lWordCount = (lByteCount - lByteCount % 4) / 4;
lBytePosition = lByteCount % 4 * 8;
lWordArray[lWordCount] = lWordArray[lWordCount] | 0x80 << lBytePosition;
lWordArray[lNumberOfWords - 2] = lMessageLength << 3;
lWordArray[lNumberOfWords - 1] = lMessageLength >>> 29;
return lWordArray;
}
function wordToHex(lValue) {
var wordToHexValue = '',
wordToHexValue_temp = '',
lByte,
lCount;
for (lCount = 0; lCount <= 3; lCount++) {
lByte = lValue >>> lCount * 8 & 255;
wordToHexValue_temp = "0".concat(lByte.toString(16));
wordToHexValue = wordToHexValue + wordToHexValue_temp.substr(wordToHexValue_temp.length - 2, 2);
}
return wordToHexValue;
}
function utf8Encode(str) {
var utftext = '';
for (var n = 0; n < str.length; n++) {
var _c = str.charCodeAt(n);
if (_c < 128) {
utftext += String.fromCharCode(_c);
} else if (_c > 127 && _c < 2048) {
utftext += String.fromCharCode(_c >> 6 | 192);
utftext += String.fromCharCode(_c & 63 | 128);
} else {
utftext += String.fromCharCode(_c >> 12 | 224);
utftext += String.fromCharCode(_c >> 6 & 63 | 128);
utftext += String.fromCharCode(_c & 63 | 128);
}
}
return utftext;
}
var x = [];
var k, AA, BB, CC, DD, a, b, c, d;
var S11 = 7,
S12 = 12,
S13 = 17,
S14 = 22;
var S21 = 5,
S22 = 9,
S23 = 14,
S24 = 20;
var S31 = 4,
S32 = 11,
S33 = 16,
S34 = 23;
var S41 = 6,
S42 = 10,
S43 = 15,
S44 = 21;
string = utf8Encode(string);
x = convertToWordArray(string);
a = 0x67452301;
b = 0xEFCDAB89;
c = 0x98BADCFE;
d = 0x10325476;
for (k = 0; k < x.length; k += 16) {
AA = a;
BB = b;
CC = c;
DD = d;
a = doFF(a, b, c, d, x[k + 0], S11, 0xD76AA478);
d = doFF(d, a, b, c, x[k + 1], S12, 0xE8C7B756);
c = doFF(c, d, a, b, x[k + 2], S13, 0x242070DB);
b = doFF(b, c, d, a, x[k + 3], S14, 0xC1BDCEEE);
a = doFF(a, b, c, d, x[k + 4], S11, 0xF57C0FAF);
d = doFF(d, a, b, c, x[k + 5], S12, 0x4787C62A);
c = doFF(c, d, a, b, x[k + 6], S13, 0xA8304613);
b = doFF(b, c, d, a, x[k + 7], S14, 0xFD469501);
a = doFF(a, b, c, d, x[k + 8], S11, 0x698098D8);
d = doFF(d, a, b, c, x[k + 9], S12, 0x8B44F7AF);
c = doFF(c, d, a, b, x[k + 10], S13, 0xFFFF5BB1);
b = doFF(b, c, d, a, x[k + 11], S14, 0x895CD7BE);
a = doFF(a, b, c, d, x[k + 12], S11, 0x6B901122);
d = doFF(d, a, b, c, x[k + 13], S12, 0xFD987193);
c = doFF(c, d, a, b, x[k + 14], S13, 0xA679438E);
b = doFF(b, c, d, a, x[k + 15], S14, 0x49B40821);
a = doGG(a, b, c, d, x[k + 1], S21, 0xF61E2562);
d = doGG(d, a, b, c, x[k + 6], S22, 0xC040B340);
c = doGG(c, d, a, b, x[k + 11], S23, 0x265E5A51);
b = doGG(b, c, d, a, x[k + 0], S24, 0xE9B6C7AA);
a = doGG(a, b, c, d, x[k + 5], S21, 0xD62F105D);
d = doGG(d, a, b, c, x[k + 10], S22, 0x2441453);
c = doGG(c, d, a, b, x[k + 15], S23, 0xD8A1E681);
b = doGG(b, c, d, a, x[k + 4], S24, 0xE7D3FBC8);
a = doGG(a, b, c, d, x[k + 9], S21, 0x21E1CDE6);
d = doGG(d, a, b, c, x[k + 14], S22, 0xC33707D6);
c = doGG(c, d, a, b, x[k + 3], S23, 0xF4D50D87);
b = doGG(b, c, d, a, x[k + 8], S24, 0x455A14ED);
a = doGG(a, b, c, d, x[k + 13], S21, 0xA9E3E905);
d = doGG(d, a, b, c, x[k + 2], S22, 0xFCEFA3F8);
c = doGG(c, d, a, b, x[k + 7], S23, 0x676F02D9);
b = doGG(b, c, d, a, x[k + 12], S24, 0x8D2A4C8A);
a = doHH(a, b, c, d, x[k + 5], S31, 0xFFFA3942);
d = doHH(d, a, b, c, x[k + 8], S32, 0x8771F681);
c = doHH(c, d, a, b, x[k + 11], S33, 0x6D9D6122);
b = doHH(b, c, d, a, x[k + 14], S34, 0xFDE5380C);
a = doHH(a, b, c, d, x[k + 1], S31, 0xA4BEEA44);
d = doHH(d, a, b, c, x[k + 4], S32, 0x4BDECFA9);
c = doHH(c, d, a, b, x[k + 7], S33, 0xF6BB4B60);
b = doHH(b, c, d, a, x[k + 10], S34, 0xBEBFBC70);
a = doHH(a, b, c, d, x[k + 13], S31, 0x289B7EC6);
d = doHH(d, a, b, c, x[k + 0], S32, 0xEAA127FA);
c = doHH(c, d, a, b, x[k + 3], S33, 0xD4EF3085);
b = doHH(b, c, d, a, x[k + 6], S34, 0x4881D05);
a = doHH(a, b, c, d, x[k + 9], S31, 0xD9D4D039);
d = doHH(d, a, b, c, x[k + 12], S32, 0xE6DB99E5);
c = doHH(c, d, a, b, x[k + 15], S33, 0x1FA27CF8);
b = doHH(b, c, d, a, x[k + 2], S34, 0xC4AC5665);
a = doII(a, b, c, d, x[k + 0], S41, 0xF4292244);
d = doII(d, a, b, c, x[k + 7], S42, 0x432AFF97);
c = doII(c, d, a, b, x[k + 14], S43, 0xAB9423A7);
b = doII(b, c, d, a, x[k + 5], S44, 0xFC93A039);
a = doII(a, b, c, d, x[k + 12], S41, 0x655B59C3);
d = doII(d, a, b, c, x[k + 3], S42, 0x8F0CCC92);
c = doII(c, d, a, b, x[k + 10], S43, 0xFFEFF47D);
b = doII(b, c, d, a, x[k + 1], S44, 0x85845DD1);
a = doII(a, b, c, d, x[k + 8], S41, 0x6FA87E4F);
d = doII(d, a, b, c, x[k + 15], S42, 0xFE2CE6E0);
c = doII(c, d, a, b, x[k + 6], S43, 0xA3014314);
b = doII(b, c, d, a, x[k + 13], S44, 0x4E0811A1);
a = doII(a, b, c, d, x[k + 4], S41, 0xF7537E82);
d = doII(d, a, b, c, x[k + 11], S42, 0xBD3AF235);
c = doII(c, d, a, b, x[k + 2], S43, 0x2AD7D2BB);
b = doII(b, c, d, a, x[k + 9], S44, 0xEB86D391);
a = addUnsigned(a, AA);
b = addUnsigned(b, BB);
c = addUnsigned(c, CC);
d = addUnsigned(d, DD);
}
var temp = wordToHex(a) + wordToHex(b) + wordToHex(c) + wordToHex(d);
return temp.toLowerCase();
};
exports.closeMediaStream = function (stream) {
if (!stream) {
return;
} // Latest spec states that MediaStream has no stop() method and instead must
// call stop() on every MediaStreamTrack.
try {
var tracks;
if (stream.getTracks) {
tracks = stream.getTracks();
var _iterator = _createForOfIteratorHelper(tracks),
_step;
try {
for (_iterator.s(); !(_step = _iterator.n()).done;) {
var track = _step.value;
track.stop();
}
} catch (err) {
_iterator.e(err);
} finally {
_iterator.f();
}
} else {
tracks = stream.getAudioTracks();
var _iterator2 = _createForOfIteratorHelper(tracks),
_step2;
try {
for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
var _track = _step2.value;
_track.stop();
}
} catch (err) {
_iterator2.e(err);
} finally {
_iterator2.f();
}
tracks = stream.getVideoTracks();
var _iterator3 = _createForOfIteratorHelper(tracks),
_step3;
try {
for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) {
var _track2 = _step3.value;
_track2.stop();
}
} catch (err) {
_iterator3.e(err);
} finally {
_iterator3.f();
}
}
} catch (error) {
// Deprecated by the spec, but still in use.
// NOTE: In Temasys IE plugin stream.stop is a callable 'object'.
if (typeof stream.stop === 'function' || _typeof(stream.stop) === 'object') {
stream.stop();
}
}
};
exports.cloneArray = function (array) {
return array && array.slice() || [];
};
exports.cloneObject = function (obj) {
var fallback = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
return obj && Object.assign({}, obj) || fallback;
};
},{"./Constants":2,"./Grammar":7,"./URI":27}],29:[function(require,module,exports){
"use strict";
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }
var Logger = require('./Logger');
var Grammar = require('./Grammar');
var logger = new Logger('WebSocketInterface');
module.exports = /*#__PURE__*/function () {
function WebSocketInterface(url) {
_classCallCheck(this, WebSocketInterface);
logger.debug('new() [url:"%s"]', url);
this._url = url;
this._sip_uri = null;
this._via_transport = null;
this._ws = null;
var parsed_url = Grammar.parse(url, 'absoluteURI');
if (parsed_url === -1) {
logger.warn("invalid WebSocket URI: ".concat(url));
throw new TypeError("Invalid argument: ".concat(url));
} else if (parsed_url.scheme !== 'wss' && parsed_url.scheme !== 'ws') {
logger.warn("invalid WebSocket URI scheme: ".concat(parsed_url.scheme));
throw new TypeError("Invalid argument: ".concat(url));
} else {
this._sip_uri = "sip:".concat(parsed_url.host).concat(parsed_url.port ? ":".concat(parsed_url.port) : '', ";transport=ws");
this._via_transport = parsed_url.scheme.toUpperCase();
}
}
_createClass(WebSocketInterface, [{
key: "connect",
value: function connect() {
logger.debug('connect()');
if (this.isConnected()) {
logger.debug("WebSocket ".concat(this._url, " is already connected"));
return;
} else if (this.isConnecting()) {
logger.debug("WebSocket ".concat(this._url, " is connecting"));
return;
}
if (this._ws) {
this.disconnect();
}
logger.debug("connecting to WebSocket ".concat(this._url));
try {
this._ws = new WebSocket(this._url, 'sip');
this._ws.binaryType = 'arraybuffer';
this._ws.onopen = this._onOpen.bind(this);
this._ws.onclose = this._onClose.bind(this);
this._ws.onmessage = this._onMessage.bind(this);
this._ws.onerror = this._onError.bind(this);
} catch (e) {
this._onError(e);
}
}
}, {
key: "disconnect",
value: function disconnect() {
logger.debug('disconnect()');
if (this._ws) {
// Unbind websocket event callbacks.
this._ws.onopen = function () {};
this._ws.onclose = function () {};
this._ws.onmessage = function () {};
this._ws.onerror = function () {};
this._ws.close();
this._ws = null;
}
}
}, {
key: "send",
value: function send(message) {
logger.debug('send()');
if (this.isConnected()) {
this._ws.send(message);
return true;
} else {
logger.warn('unable to send message, WebSocket is not open');
return false;
}
}
}, {
key: "isConnected",
value: function isConnected() {
return this._ws && this._ws.readyState === this._ws.OPEN;
}
}, {
key: "isConnecting",
value: function isConnecting() {
return this._ws && this._ws.readyState === this._ws.CONNECTING;
}
/**
* WebSocket Event Handlers
*/
}, {
key: "_onOpen",
value: function _onOpen() {
logger.debug("WebSocket ".concat(this._url, " connected"));
this.onconnect();
}
}, {
key: "_onClose",
value: function _onClose(_ref) {
var wasClean = _ref.wasClean,
code = _ref.code,
reason = _ref.reason;
logger.debug("WebSocket ".concat(this._url, " closed"));
if (wasClean === false) {
logger.debug('WebSocket abrupt disconnection');
}
this.ondisconnect(!wasClean, code, reason);
}
}, {
key: "_onMessage",
value: function _onMessage(_ref2) {
var data = _ref2.data;
logger.debug('received WebSocket message');
this.ondata(data);
}
}, {
key: "_onError",
value: function _onError(e) {
logger.warn("WebSocket ".concat(this._url, " error: "), e);
}
}, {
key: "via_transport",
get: function get() {
return this._via_transport;
},
set: function set(value) {
this._via_transport = value.toUpperCase();
}
}, {
key: "sip_uri",
get: function get() {
return this._sip_uri;
}
}, {
key: "url",
get: function get() {
return this._url;
}
}]);
return WebSocketInterface;
}();
},{"./Grammar":7,"./Logger":9}],30:[function(require,module,exports){
"use strict";
function _createForOfIteratorHelper(o, allowArrayLike) { var it; if (typeof Symbol === "undefined" || o[Symbol.iterator] == null) { if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = o[Symbol.iterator](); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it["return"] != null) it["return"](); } finally { if (didErr) throw err; } } }; }
function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }
var Logger = require('./Logger');
var SimpleSIP_C = require('./Constants');
var SIPMessage = require('./SIPMessage');
var Utils = require('./Utils');
var logger = new Logger('sanityCheck'); // Checks for requests and responses.
var all = [minimumHeaders]; // Checks for requests.
var requests = [rfc3261_8_2_2_1, rfc3261_16_3_4, rfc3261_18_3_request, rfc3261_8_2_2_2]; // Checks for responses.
var responses = [rfc3261_8_1_3_3, rfc3261_18_3_response]; // local variables.
var message;
var ua;
var transport;
module.exports = function (m, u, t) {
message = m;
ua = u;
transport = t;
var _iterator = _createForOfIteratorHelper(all),
_step;
try {
for (_iterator.s(); !(_step = _iterator.n()).done;) {
var _check2 = _step.value;
if (_check2() === false) {
return false;
}
}
} catch (err) {
_iterator.e(err);
} finally {
_iterator.f();
}
if (message instanceof SIPMessage.IncomingRequest) {
var _iterator2 = _createForOfIteratorHelper(requests),
_step2;
try {
for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
var check = _step2.value;
if (check() === false) {
return false;
}
}
} catch (err) {
_iterator2.e(err);
} finally {
_iterator2.f();
}
} else if (message instanceof SIPMessage.IncomingResponse) {
var _iterator3 = _createForOfIteratorHelper(responses),
_step3;
try {
for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) {
var _check = _step3.value;
if (_check() === false) {
return false;
}
}
} catch (err) {
_iterator3.e(err);
} finally {
_iterator3.f();
}
} // Everything is OK.
return true;
};
/*
* Sanity Check for incoming Messages
*
* Requests:
* - _rfc3261_8_2_2_1_ Receive a Request with a non supported URI scheme
* - _rfc3261_16_3_4_ Receive a Request already sent by us
* Does not look at via sent-by but at SimpleSIP_id, which is inserted as
* a prefix in all initial requests generated by the ua
* - _rfc3261_18_3_request_ Body Content-Length
* - _rfc3261_8_2_2_2_ Merged Requests
*
* Responses:
* - _rfc3261_8_1_3_3_ Multiple Via headers
* - _rfc3261_18_3_response_ Body Content-Length
*
* All:
* - Minimum headers in a SIP message
*/
// Sanity Check functions for requests.
function rfc3261_8_2_2_1() {
if (message.s('to').uri.scheme !== 'sip') {
reply(416);
return false;
}
}
function rfc3261_16_3_4() {
if (!message.to_tag) {
if (message.call_id.substr(0, 5) === ua.configuration.SimpleSIP_id) {
reply(482);
return false;
}
}
}
function rfc3261_18_3_request() {
var len = Utils.str_utf8_length(message.body);
var contentLength = message.getHeader('content-length');
if (len < contentLength) {
reply(400);
return false;
}
}
function rfc3261_8_2_2_2() {
var fromTag = message.from_tag;
var call_id = message.call_id;
var cseq = message.cseq;
var tr; // Accept any in-dialog request.
if (message.to_tag) {
return;
} // INVITE request.
if (message.method === SimpleSIP_C.INVITE) {
// If the branch matches the key of any IST then assume it is a retransmission
// and ignore the INVITE.
// TODO: we should reply the last response.
if (ua._transactions.ist[message.via_branch]) {
return false;
} // Otherwise check whether it is a merged request.
else {
for (var transaction in ua._transactions.ist) {
if (Object.prototype.hasOwnProperty.call(ua._transactions.ist, transaction)) {
tr = ua._transactions.ist[transaction];
if (tr.request.from_tag === fromTag && tr.request.call_id === call_id && tr.request.cseq === cseq) {
reply(482);
return false;
}
}
}
}
} // Non INVITE request.
// If the branch matches the key of any NIST then assume it is a retransmission
// and ignore the request.
// TODO: we should reply the last response.
else if (ua._transactions.nist[message.via_branch]) {
return false;
} // Otherwise check whether it is a merged request.
else {
for (var _transaction in ua._transactions.nist) {
if (Object.prototype.hasOwnProperty.call(ua._transactions.nist, _transaction)) {
tr = ua._transactions.nist[_transaction];
if (tr.request.from_tag === fromTag && tr.request.call_id === call_id && tr.request.cseq === cseq) {
reply(482);
return false;
}
}
}
}
} // Sanity Check functions for responses.
function rfc3261_8_1_3_3() {
if (message.getHeaders('via').length > 1) {
logger.debug('more than one Via header field present in the response, dropping the response');
return false;
}
}
function rfc3261_18_3_response() {
var len = Utils.str_utf8_length(message.body),
contentLength = message.getHeader('content-length');
if (len < contentLength) {
logger.debug('message body length is lower than the value in Content-Length header field, dropping the response');
return false;
}
} // Sanity Check functions for requests and responses.
function minimumHeaders() {
var mandatoryHeaders = ['from', 'to', 'call_id', 'cseq', 'via'];
for (var _i = 0, _mandatoryHeaders = mandatoryHeaders; _i < _mandatoryHeaders.length; _i++) {
var header = _mandatoryHeaders[_i];
if (!message.hasHeader(header)) {
logger.debug("missing mandatory header field : ".concat(header, ", dropping the response"));
return false;
}
}
} // Reply.
function reply(status_code) {
var vias = message.getHeaders('via');
var to;
var response = "SIP/2.0 ".concat(status_code, " ").concat(SimpleSIP_C.REASON_PHRASE[status_code], "\r\n");
var _iterator4 = _createForOfIteratorHelper(vias),
_step4;
try {
for (_iterator4.s(); !(_step4 = _iterator4.n()).done;) {
var via = _step4.value;
response += "Via: ".concat(via, "\r\n");
}
} catch (err) {
_iterator4.e(err);
} finally {
_iterator4.f();
}
to = message.getHeader('To');
if (!message.to_tag) {
to += ";tag=".concat(Utils.newTag());
}
response += "To: ".concat(to, "\r\n");
response += "From: ".concat(message.getHeader('From'), "\r\n");
response += "Call-ID: ".concat(message.call_id, "\r\n");
response += "CSeq: ".concat(message.cseq, " ").concat(message.method, "\r\n");
response += '\r\n';
transport.send(response);
}
},{"./Constants":2,"./Logger":9,"./SIPMessage":21,"./Utils":28}],31:[function(require,module,exports){
// Copyright Joyent, Inc. and other Node contributors.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to permit
// persons to whom the Software is furnished to do so, subject to the
// following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE.
var objectCreate = Object.create || objectCreatePolyfill
var objectKeys = Object.keys || objectKeysPolyfill
var bind = Function.prototype.bind || functionBindPolyfill
function EventEmitter() {
if (!this._events || !Object.prototype.hasOwnProperty.call(this, '_events')) {
this._events = objectCreate(null);
this._eventsCount = 0;
}
this._maxListeners = this._maxListeners || undefined;
}
module.exports = EventEmitter;
// Backwards-compat with node 0.10.x
EventEmitter.EventEmitter = EventEmitter;
EventEmitter.prototype._events = undefined;
EventEmitter.prototype._maxListeners = undefined;
// By default EventEmitters will print a warning if more than 10 listeners are
// added to it. This is a useful default which helps finding memory leaks.
var defaultMaxListeners = 10;
var hasDefineProperty;
try {
var o = {};
if (Object.defineProperty) Object.defineProperty(o, 'x', { value: 0 });
hasDefineProperty = o.x === 0;
} catch (err) { hasDefineProperty = false }
if (hasDefineProperty) {
Object.defineProperty(EventEmitter, 'defaultMaxListeners', {
enumerable: true,
get: function() {
return defaultMaxListeners;
},
set: function(arg) {
// check whether the input is a positive number (whose value is zero or
// greater and not a NaN).
if (typeof arg !== 'number' || arg < 0 || arg !== arg)
throw new TypeError('"defaultMaxListeners" must be a positive number');
defaultMaxListeners = arg;
}
});
} else {
EventEmitter.defaultMaxListeners = defaultMaxListeners;
}
// Obviously not all Emitters should be limited to 10. This function allows
// that to be increased. Set to zero for unlimited.
EventEmitter.prototype.setMaxListeners = function setMaxListeners(n) {
if (typeof n !== 'number' || n < 0 || isNaN(n))
throw new TypeError('"n" argument must be a positive number');
this._maxListeners = n;
return this;
};
function $getMaxListeners(that) {
if (that._maxListeners === undefined)
return EventEmitter.defaultMaxListeners;
return that._maxListeners;
}
EventEmitter.prototype.getMaxListeners = function getMaxListeners() {
return $getMaxListeners(this);
};
// These standalone emit* functions are used to optimize calling of event
// handlers for fast cases because emit() itself often has a variable number of
// arguments and can be deoptimized because of that. These functions always have
// the same number of arguments and thus do not get deoptimized, so the code
// inside them can execute faster.
function emitNone(handler, isFn, self) {
if (isFn)
handler.call(self);
else {
var len = handler.length;
var listeners = arrayClone(handler, len);
for (var i = 0; i < len; ++i)
listeners[i].call(self);
}
}
function emitOne(handler, isFn, self, arg1) {
if (isFn)
handler.call(self, arg1);
else {
var len = handler.length;
var listeners = arrayClone(handler, len);
for (var i = 0; i < len; ++i)
listeners[i].call(self, arg1);
}
}
function emitTwo(handler, isFn, self, arg1, arg2) {
if (isFn)
handler.call(self, arg1, arg2);
else {
var len = handler.length;
var listeners = arrayClone(handler, len);
for (var i = 0; i < len; ++i)
listeners[i].call(self, arg1, arg2);
}
}
function emitThree(handler, isFn, self, arg1, arg2, arg3) {
if (isFn)
handler.call(self, arg1, arg2, arg3);
else {
var len = handler.length;
var listeners = arrayClone(handler, len);
for (var i = 0; i < len; ++i)
listeners[i].call(self, arg1, arg2, arg3);
}
}
function emitMany(handler, isFn, self, args) {
if (isFn)
handler.apply(self, args);
else {
var len = handler.length;
var listeners = arrayClone(handler, len);
for (var i = 0; i < len; ++i)
listeners[i].apply(self, args);
}
}
EventEmitter.prototype.emit = function emit(type) {
var er, handler, len, args, i, events;
var doError = (type === 'error');
events = this._events;
if (events)
doError = (doError && events.error == null);
else if (!doError)
return false;
// If there is no 'error' event listener then throw.
if (doError) {
if (arguments.length > 1)
er = arguments[1];
if (er instanceof Error) {
throw er; // Unhandled 'error' event
} else {
// At least give some kind of context to the user
var err = new Error('Unhandled "error" event. (' + er + ')');
err.context = er;
throw err;
}
return false;
}
handler = events[type];
if (!handler)
return false;
var isFn = typeof handler === 'function';
len = arguments.length;
switch (len) {
// fast cases
case 1:
emitNone(handler, isFn, this);
break;
case 2:
emitOne(handler, isFn, this, arguments[1]);
break;
case 3:
emitTwo(handler, isFn, this, arguments[1], arguments[2]);
break;
case 4:
emitThree(handler, isFn, this, arguments[1], arguments[2], arguments[3]);
break;
// slower
default:
args = new Array(len - 1);
for (i = 1; i < len; i++)
args[i - 1] = arguments[i];
emitMany(handler, isFn, this, args);
}
return true;
};
function _addListener(target, type, listener, prepend) {
var m;
var events;
var existing;
if (typeof listener !== 'function')
throw new TypeError('"listener" argument must be a function');
events = target._events;
if (!events) {
events = target._events = objectCreate(null);
target._eventsCount = 0;
} else {
// To avoid recursion in the case that type === "newListener"! Before
// adding it to the listeners, first emit "newListener".
if (events.newListener) {
target.emit('newListener', type,
listener.listener ? listener.listener : listener);
// Re-assign `events` because a newListener handler could have caused the
// this._events to be assigned to a new object
events = target._events;
}
existing = events[type];
}
if (!existing) {
// Optimize the case of one listener. Don't need the extra array object.
existing = events[type] = listener;
++target._eventsCount;
} else {
if (typeof existing === 'function') {
// Adding the second element, need to change to array.
existing = events[type] =
prepend ? [listener, existing] : [existing, listener];
} else {
// If we've already got an array, just append.
if (prepend) {
existing.unshift(listener);
} else {
existing.push(listener);
}
}
// Check for listener leak
if (!existing.warned) {
m = $getMaxListeners(target);
if (m && m > 0 && existing.length > m) {
existing.warned = true;
var w = new Error('Possible EventEmitter memory leak detected. ' +
existing.length + ' "' + String(type) + '" listeners ' +
'added. Use emitter.setMaxListeners() to ' +
'increase limit.');
w.name = 'MaxListenersExceededWarning';
w.emitter = target;
w.type = type;
w.count = existing.length;
if (typeof console === 'object' && console.warn) {
console.warn('%s: %s', w.name, w.message);
}
}
}
}
return target;
}
EventEmitter.prototype.addListener = function addListener(type, listener) {
return _addListener(this, type, listener, false);
};
EventEmitter.prototype.on = EventEmitter.prototype.addListener;
EventEmitter.prototype.prependListener =
function prependListener(type, listener) {
return _addListener(this, type, listener, true);
};
function onceWrapper() {
if (!this.fired) {
this.target.removeListener(this.type, this.wrapFn);
this.fired = true;
switch (arguments.length) {
case 0:
return this.listener.call(this.target);
case 1:
return this.listener.call(this.target, arguments[0]);
case 2:
return this.listener.call(this.target, arguments[0], arguments[1]);
case 3:
return this.listener.call(this.target, arguments[0], arguments[1],
arguments[2]);
default:
var args = new Array(arguments.length);
for (var i = 0; i < args.length; ++i)
args[i] = arguments[i];
this.listener.apply(this.target, args);
}
}
}
function _onceWrap(target, type, listener) {
var state = { fired: false, wrapFn: undefined, target: target, type: type, listener: listener };
var wrapped = bind.call(onceWrapper, state);
wrapped.listener = listener;
state.wrapFn = wrapped;
return wrapped;
}
EventEmitter.prototype.once = function once(type, listener) {
if (typeof listener !== 'function')
throw new TypeError('"listener" argument must be a function');
this.on(type, _onceWrap(this, type, listener));
return this;
};
EventEmitter.prototype.prependOnceListener =
function prependOnceListener(type, listener) {
if (typeof listener !== 'function')
throw new TypeError('"listener" argument must be a function');
this.prependListener(type, _onceWrap(this, type, listener));
return this;
};
// Emits a 'removeListener' event if and only if the listener was removed.
EventEmitter.prototype.removeListener =
function removeListener(type, listener) {
var list, events, position, i, originalListener;
if (typeof listener !== 'function')
throw new TypeError('"listener" argument must be a function');
events = this._events;
if (!events)
return this;
list = events[type];
if (!list)
return this;
if (list === listener || list.listener === listener) {
if (--this._eventsCount === 0)
this._events = objectCreate(null);
else {
delete events[type];
if (events.removeListener)
this.emit('removeListener', type, list.listener || listener);
}
} else if (typeof list !== 'function') {
position = -1;
for (i = list.length - 1; i >= 0; i--) {
if (list[i] === listener || list[i].listener === listener) {
originalListener = list[i].listener;
position = i;
break;
}
}
if (position < 0)
return this;
if (position === 0)
list.shift();
else
spliceOne(list, position);
if (list.length === 1)
events[type] = list[0];
if (events.removeListener)
this.emit('removeListener', type, originalListener || listener);
}
return this;
};
EventEmitter.prototype.removeAllListeners =
function removeAllListeners(type) {
var listeners, events, i;
events = this._events;
if (!events)
return this;
// not listening for removeListener, no need to emit
if (!events.removeListener) {
if (arguments.length === 0) {
this._events = objectCreate(null);
this._eventsCount = 0;
} else if (events[type]) {
if (--this._eventsCount === 0)
this._events = objectCreate(null);
else
delete events[type];
}
return this;
}
// emit removeListener for all listeners on all events
if (arguments.length === 0) {
var keys = objectKeys(events);
var key;
for (i = 0; i < keys.length; ++i) {
key = keys[i];
if (key === 'removeListener') continue;
this.removeAllListeners(key);
}
this.removeAllListeners('removeListener');
this._events = objectCreate(null);
this._eventsCount = 0;
return this;
}
listeners = events[type];
if (typeof listeners === 'function') {
this.removeListener(type, listeners);
} else if (listeners) {
// LIFO order
for (i = listeners.length - 1; i >= 0; i--) {
this.removeListener(type, listeners[i]);
}
}
return this;
};
function _listeners(target, type, unwrap) {
var events = target._events;
if (!events)
return [];
var evlistener = events[type];
if (!evlistener)
return [];
if (typeof evlistener === 'function')
return unwrap ? [evlistener.listener || evlistener] : [evlistener];
return unwrap ? unwrapListeners(evlistener) : arrayClone(evlistener, evlistener.length);
}
EventEmitter.prototype.listeners = function listeners(type) {
return _listeners(this, type, true);
};
EventEmitter.prototype.rawListeners = function rawListeners(type) {
return _listeners(this, type, false);
};
EventEmitter.listenerCount = function(emitter, type) {
if (typeof emitter.listenerCount === 'function') {
return emitter.listenerCount(type);
} else {
return listenerCount.call(emitter, type);
}
};
EventEmitter.prototype.listenerCount = listenerCount;
function listenerCount(type) {
var events = this._events;
if (events) {
var evlistener = events[type];
if (typeof evlistener === 'function') {
return 1;
} else if (evlistener) {
return evlistener.length;
}
}
return 0;
}
EventEmitter.prototype.eventNames = function eventNames() {
return this._eventsCount > 0 ? Reflect.ownKeys(this._events) : [];
};
// About 1.5x faster than the two-arg version of Array#splice().
function spliceOne(list, index) {
for (var i = index, k = i + 1, n = list.length; k < n; i += 1, k += 1)
list[i] = list[k];
list.pop();
}
function arrayClone(arr, n) {
var copy = new Array(n);
for (var i = 0; i < n; ++i)
copy[i] = arr[i];
return copy;
}
function unwrapListeners(arr) {
var ret = new Array(arr.length);
for (var i = 0; i < ret.length; ++i) {
ret[i] = arr[i].listener || arr[i];
}
return ret;
}
function objectCreatePolyfill(proto) {
var F = function() {};
F.prototype = proto;
return new F;
}
function objectKeysPolyfill(obj) {
var keys = [];
for (var k in obj) if (Object.prototype.hasOwnProperty.call(obj, k)) {
keys.push(k);
}
return k;
}
function functionBindPolyfill(context) {
var fn = this;
return function () {
return fn.apply(context, arguments);
};
}
},{}],32:[function(require,module,exports){
(function (process){
/* eslint-env browser */
/**
* This is the web browser implementation of `debug()`.
*/
exports.log = log;
exports.formatArgs = formatArgs;
exports.save = save;
exports.load = load;
exports.useColors = useColors;
exports.storage = localstorage();
/**
* Colors.
*/
exports.colors = [
'#0000CC',
'#0000FF',
'#0033CC',
'#0033FF',
'#0066CC',
'#0066FF',
'#0099CC',
'#0099FF',
'#00CC00',
'#00CC33',
'#00CC66',
'#00CC99',
'#00CCCC',
'#00CCFF',
'#3300CC',
'#3300FF',
'#3333CC',
'#3333FF',
'#3366CC',
'#3366FF',
'#3399CC',
'#3399FF',
'#33CC00',
'#33CC33',
'#33CC66',
'#33CC99',
'#33CCCC',
'#33CCFF',
'#6600CC',
'#6600FF',
'#6633CC',
'#6633FF',
'#66CC00',
'#66CC33',
'#9900CC',
'#9900FF',
'#9933CC',
'#9933FF',
'#99CC00',
'#99CC33',
'#CC0000',
'#CC0033',
'#CC0066',
'#CC0099',
'#CC00CC',
'#CC00FF',
'#CC3300',
'#CC3333',
'#CC3366',
'#CC3399',
'#CC33CC',
'#CC33FF',
'#CC6600',
'#CC6633',
'#CC9900',
'#CC9933',
'#CCCC00',
'#CCCC33',
'#FF0000',
'#FF0033',
'#FF0066',
'#FF0099',
'#FF00CC',
'#FF00FF',
'#FF3300',
'#FF3333',
'#FF3366',
'#FF3399',
'#FF33CC',
'#FF33FF',
'#FF6600',
'#FF6633',
'#FF9900',
'#FF9933',
'#FFCC00',
'#FFCC33'
];
/**
* Currently only WebKit-based Web Inspectors, Firefox >= v31,
* and the Firebug extension (any Firefox version) are known
* to support "%c" CSS customizations.
*
* TODO: add a `localStorage` variable to explicitly enable/disable colors
*/
// eslint-disable-next-line complexity
function useColors() {
// NB: In an Electron preload script, document will be defined but not fully
// initialized. Since we know we're in Chrome, we'll just detect this case
// explicitly
if (typeof window !== 'undefined' && window.process && (window.process.type === 'renderer' || window.process.__nwjs)) {
return true;
}
// Internet Explorer and Edge do not support colors.
if (typeof navigator !== 'undefined' && navigator.userAgent && navigator.userAgent.toLowerCase().match(/(edge|trident)\/(\d+)/)) {
return false;
}
// Is webkit? http://stackoverflow.com/a/16459606/376773
// document is undefined in react-native: https://github.com/facebook/react-native/pull/1632
return (typeof document !== 'undefined' && document.documentElement && document.documentElement.style && document.documentElement.style.WebkitAppearance) ||
// Is firebug? http://stackoverflow.com/a/398120/376773
(typeof window !== 'undefined' && window.console && (window.console.firebug || (window.console.exception && window.console.table))) ||
// Is firefox >= v31?
// https://developer.mozilla.org/en-US/docs/Tools/Web_Console#Styling_messages
(typeof navigator !== 'undefined' && navigator.userAgent && navigator.userAgent.toLowerCase().match(/firefox\/(\d+)/) && parseInt(RegExp.$1, 10) >= 31) ||
// Double check webkit in userAgent just in case we are in a worker
(typeof navigator !== 'undefined' && navigator.userAgent && navigator.userAgent.toLowerCase().match(/applewebkit\/(\d+)/));
}
/**
* Colorize log arguments if enabled.
*
* @api public
*/
function formatArgs(args) {
args[0] = (this.useColors ? '%c' : '') +
this.namespace +
(this.useColors ? ' %c' : ' ') +
args[0] +
(this.useColors ? '%c ' : ' ') +
'+' + module.exports.humanize(this.diff);
if (!this.useColors) {
return;
}
const c = 'color: ' + this.color;
args.splice(1, 0, c, 'color: inherit');
// The final "%c" is somewhat tricky, because there could be other
// arguments passed either before or after the %c, so we need to
// figure out the correct index to insert the CSS into
let index = 0;
let lastC = 0;
args[0].replace(/%[a-zA-Z%]/g, match => {
if (match === '%%') {
return;
}
index++;
if (match === '%c') {
// We only are interested in the *last* %c
// (the user may have provided their own)
lastC = index;
}
});
args.splice(lastC, 0, c);
}
/**
* Invokes `console.log()` when available.
* No-op when `console.log` is not a "function".
*
* @api public
*/
function log(...args) {
// This hackery is required for IE8/9, where
// the `console.log` function doesn't have 'apply'
return typeof console === 'object' &&
console.log &&
console.log(...args);
}
/**
* Save `namespaces`.
*
* @param {String} namespaces
* @api private
*/
function save(namespaces) {
try {
if (namespaces) {
exports.storage.setItem('debug', namespaces);
} else {
exports.storage.removeItem('debug');
}
} catch (error) {
// Swallow
// XXX (@Qix-) should we be logging these?
}
}
/**
* Load `namespaces`.
*
* @return {String} returns the previously persisted debug modes
* @api private
*/
function load() {
let r;
try {
r = exports.storage.getItem('debug');
} catch (error) {
// Swallow
// XXX (@Qix-) should we be logging these?
}
// If debug isn't set in LS, and we're in Electron, try to load $DEBUG
if (!r && typeof process !== 'undefined' && 'env' in process) {
r = process.env.DEBUG;
}
return r;
}
/**
* Localstorage attempts to return the localstorage.
*
* This is necessary because safari throws
* when a user disables cookies/localstorage
* and you attempt to access it.
*
* @return {LocalStorage}
* @api private
*/
function localstorage() {
try {
// TVMLKit (Apple TV JS Runtime) does not have a window object, just localStorage in the global context
// The Browser also has localStorage in the global context.
return localStorage;
} catch (error) {
// Swallow
// XXX (@Qix-) should we be logging these?
}
}
module.exports = require('./common')(exports);
const {formatters} = module.exports;
/**
* Map %j to `JSON.stringify()`, since no Web Inspectors do that by default.
*/
formatters.j = function (v) {
try {
return JSON.stringify(v);
} catch (error) {
return '[UnexpectedJSONParseError]: ' + error.message;
}
};
}).call(this,require('_process'))
},{"./common":33,"_process":35}],33:[function(require,module,exports){
/**
* This is the common logic for both the Node.js and web browser
* implementations of `debug()`.
*/
function setup(env) {
createDebug.debug = createDebug;
createDebug.default = createDebug;
createDebug.coerce = coerce;
createDebug.disable = disable;
createDebug.enable = enable;
createDebug.enabled = enabled;
createDebug.humanize = require('ms');
Object.keys(env).forEach(key => {
createDebug[key] = env[key];
});
/**
* Active `debug` instances.
*/
createDebug.instances = [];
/**
* The currently active debug mode names, and names to skip.
*/
createDebug.names = [];
createDebug.skips = [];
/**
* Map of special "%n" handling functions, for the debug "format" argument.
*
* Valid key names are a single, lower or upper-case letter, i.e. "n" and "N".
*/
createDebug.formatters = {};
/**
* Selects a color for a debug namespace
* @param {String} namespace The namespace string for the for the debug instance to be colored
* @return {Number|String} An ANSI color code for the given namespace
* @api private
*/
function selectColor(namespace) {
let hash = 0;
for (let i = 0; i < namespace.length; i++) {
hash = ((hash << 5) - hash) + namespace.charCodeAt(i);
hash |= 0; // Convert to 32bit integer
}
return createDebug.colors[Math.abs(hash) % createDebug.colors.length];
}
createDebug.selectColor = selectColor;
/**
* Create a debugger with the given `namespace`.
*
* @param {String} namespace
* @return {Function}
* @api public
*/
function createDebug(namespace) {
let prevTime;
function debug(...args) {
// Disabled?
if (!debug.enabled) {
return;
}
const self = debug;
// Set `diff` timestamp
const curr = Number(new Date());
const ms = curr - (prevTime || curr);
self.diff = ms;
self.prev = prevTime;
self.curr = curr;
prevTime = curr;
args[0] = createDebug.coerce(args[0]);
if (typeof args[0] !== 'string') {
// Anything else let's inspect with %O
args.unshift('%O');
}
// Apply any `formatters` transformations
let index = 0;
args[0] = args[0].replace(/%([a-zA-Z%])/g, (match, format) => {
// If we encounter an escaped % then don't increase the array index
if (match === '%%') {
return match;
}
index++;
const formatter = createDebug.formatters[format];
if (typeof formatter === 'function') {
const val = args[index];
match = formatter.call(self, val);
// Now we need to remove `args[index]` since it's inlined in the `format`
args.splice(index, 1);
index--;
}
return match;
});
// Apply env-specific formatting (colors, etc.)
createDebug.formatArgs.call(self, args);
const logFn = self.log || createDebug.log;
logFn.apply(self, args);
}
debug.namespace = namespace;
debug.enabled = createDebug.enabled(namespace);
debug.useColors = createDebug.useColors();
debug.color = selectColor(namespace);
debug.destroy = destroy;
debug.extend = extend;
// Debug.formatArgs = formatArgs;
// debug.rawLog = rawLog;
// env-specific initialization logic for debug instances
if (typeof createDebug.init === 'function') {
createDebug.init(debug);
}
createDebug.instances.push(debug);
return debug;
}
function destroy() {
const index = createDebug.instances.indexOf(this);
if (index !== -1) {
createDebug.instances.splice(index, 1);
return true;
}
return false;
}
function extend(namespace, delimiter) {
const newDebug = createDebug(this.namespace + (typeof delimiter === 'undefined' ? ':' : delimiter) + namespace);
newDebug.log = this.log;
return newDebug;
}
/**
* Enables a debug mode by namespaces. This can include modes
* separated by a colon and wildcards.
*
* @param {String} namespaces
* @api public
*/
function enable(namespaces) {
createDebug.save(namespaces);
createDebug.names = [];
createDebug.skips = [];
let i;
const split = (typeof namespaces === 'string' ? namespaces : '').split(/[\s,]+/);
const len = split.length;
for (i = 0; i < len; i++) {
if (!split[i]) {
// ignore empty strings
continue;
}
namespaces = split[i].replace(/\*/g, '.*?');
if (namespaces[0] === '-') {
createDebug.skips.push(new RegExp('^' + namespaces.substr(1) + '$'));
} else {
createDebug.names.push(new RegExp('^' + namespaces + '$'));
}
}
for (i = 0; i < createDebug.instances.length; i++) {
const instance = createDebug.instances[i];
instance.enabled = createDebug.enabled(instance.namespace);
}
}
/**
* Disable debug output.
*
* @return {String} namespaces
* @api public
*/
function disable() {
const namespaces = [
...createDebug.names.map(toNamespace),
...createDebug.skips.map(toNamespace).map(namespace => '-' + namespace)
].join(',');
createDebug.enable('');
return namespaces;
}
/**
* Returns true if the given mode name is enabled, false otherwise.
*
* @param {String} name
* @return {Boolean}
* @api public
*/
function enabled(name) {
if (name[name.length - 1] === '*') {
return true;
}
let i;
let len;
for (i = 0, len = createDebug.skips.length; i < len; i++) {
if (createDebug.skips[i].test(name)) {
return false;
}
}
for (i = 0, len = createDebug.names.length; i < len; i++) {
if (createDebug.names[i].test(name)) {
return true;
}
}
return false;
}
/**
* Convert regexp to namespace
*
* @param {RegExp} regxep
* @return {String} namespace
* @api private
*/
function toNamespace(regexp) {
return regexp.toString()
.substring(2, regexp.toString().length - 2)
.replace(/\.\*\?$/, '*');
}
/**
* Coerce `val`.
*
* @param {Mixed} val
* @return {Mixed}
* @api private
*/
function coerce(val) {
if (val instanceof Error) {
return val.stack || val.message;
}
return val;
}
createDebug.enable(createDebug.load());
return createDebug;
}
module.exports = setup;
},{"ms":34}],34:[function(require,module,exports){
/**
* Helpers.
*/
var s = 1000;
var m = s * 60;
var h = m * 60;
var d = h * 24;
var w = d * 7;
var y = d * 365.25;
/**
* Parse or format the given `val`.
*
* Options:
*
* - `long` verbose formatting [false]
*
* @param {String|Number} val
* @param {Object} [options]
* @throws {Error} throw an error if val is not a non-empty string or a number
* @return {String|Number}
* @api public
*/
module.exports = function(val, options) {
options = options || {};
var type = typeof val;
if (type === 'string' && val.length > 0) {
return parse(val);
} else if (type === 'number' && isFinite(val)) {
return options.long ? fmtLong(val) : fmtShort(val);
}
throw new Error(
'val is not a non-empty string or a valid number. val=' +
JSON.stringify(val)
);
};
/**
* Parse the given `str` and return milliseconds.
*
* @param {String} str
* @return {Number}
* @api private
*/
function parse(str) {
str = String(str);
if (str.length > 100) {
return;
}
var match = /^(-?(?:\d+)?\.?\d+) *(milliseconds?|msecs?|ms|seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|weeks?|w|years?|yrs?|y)?$/i.exec(
str
);
if (!match) {
return;
}
var n = parseFloat(match[1]);
var type = (match[2] || 'ms').toLowerCase();
switch (type) {
case 'years':
case 'year':
case 'yrs':
case 'yr':
case 'y':
return n * y;
case 'weeks':
case 'week':
case 'w':
return n * w;
case 'days':
case 'day':
case 'd':
return n * d;
case 'hours':
case 'hour':
case 'hrs':
case 'hr':
case 'h':
return n * h;
case 'minutes':
case 'minute':
case 'mins':
case 'min':
case 'm':
return n * m;
case 'seconds':
case 'second':
case 'secs':
case 'sec':
case 's':
return n * s;
case 'milliseconds':
case 'millisecond':
case 'msecs':
case 'msec':
case 'ms':
return n;
default:
return undefined;
}
}
/**
* Short format for `ms`.
*
* @param {Number} ms
* @return {String}
* @api private
*/
function fmtShort(ms) {
var msAbs = Math.abs(ms);
if (msAbs >= d) {
return Math.round(ms / d) + 'd';
}
if (msAbs >= h) {
return Math.round(ms / h) + 'h';
}
if (msAbs >= m) {
return Math.round(ms / m) + 'm';
}
if (msAbs >= s) {
return Math.round(ms / s) + 's';
}
return ms + 'ms';
}
/**
* Long format for `ms`.
*
* @param {Number} ms
* @return {String}
* @api private
*/
function fmtLong(ms) {
var msAbs = Math.abs(ms);
if (msAbs >= d) {
return plural(ms, msAbs, d, 'day');
}
if (msAbs >= h) {
return plural(ms, msAbs, h, 'hour');
}
if (msAbs >= m) {
return plural(ms, msAbs, m, 'minute');
}
if (msAbs >= s) {
return plural(ms, msAbs, s, 'second');
}
return ms + ' ms';
}
/**
* Pluralization helper.
*/
function plural(ms, msAbs, n, name) {
var isPlural = msAbs >= n * 1.5;
return Math.round(ms / n) + ' ' + name + (isPlural ? 's' : '');
}
},{}],35:[function(require,module,exports){
// shim for using process in browser
var process = module.exports = {};
// cached from whatever global is present so that test runners that stub it
// don't break things. But we need to wrap it in a try catch in case it is
// wrapped in strict mode code which doesn't define any globals. It's inside a
// function because try/catches deoptimize in certain engines.
var cachedSetTimeout;
var cachedClearTimeout;
function defaultSetTimout() {
throw new Error('setTimeout has not been defined');
}
function defaultClearTimeout () {
throw new Error('clearTimeout has not been defined');
}
(function () {
try {
if (typeof setTimeout === 'function') {
cachedSetTimeout = setTimeout;
} else {
cachedSetTimeout = defaultSetTimout;
}
} catch (e) {
cachedSetTimeout = defaultSetTimout;
}
try {
if (typeof clearTimeout === 'function') {
cachedClearTimeout = clearTimeout;
} else {
cachedClearTimeout = defaultClearTimeout;
}
} catch (e) {
cachedClearTimeout = defaultClearTimeout;
}
} ())
function runTimeout(fun) {
if (cachedSetTimeout === setTimeout) {
//normal enviroments in sane situations
return setTimeout(fun, 0);
}
// if setTimeout wasn't available but was latter defined
if ((cachedSetTimeout === defaultSetTimout || !cachedSetTimeout) && setTimeout) {
cachedSetTimeout = setTimeout;
return setTimeout(fun, 0);
}
try {
// when when somebody has screwed with setTimeout but no I.E. maddness
return cachedSetTimeout(fun, 0);
} catch(e){
try {
// When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally
return cachedSetTimeout.call(null, fun, 0);
} catch(e){
// same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error
return cachedSetTimeout.call(this, fun, 0);
}
}
}
function runClearTimeout(marker) {
if (cachedClearTimeout === clearTimeout) {
//normal enviroments in sane situations
return clearTimeout(marker);
}
// if clearTimeout wasn't available but was latter defined
if ((cachedClearTimeout === defaultClearTimeout || !cachedClearTimeout) && clearTimeout) {
cachedClearTimeout = clearTimeout;
return clearTimeout(marker);
}
try {
// when when somebody has screwed with setTimeout but no I.E. maddness
return cachedClearTimeout(marker);
} catch (e){
try {
// When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally
return cachedClearTimeout.call(null, marker);
} catch (e){
// same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error.
// Some versions of I.E. have different rules for clearTimeout vs setTimeout
return cachedClearTimeout.call(this, marker);
}
}
}
var queue = [];
var draining = false;
var currentQueue;
var queueIndex = -1;
function cleanUpNextTick() {
if (!draining || !currentQueue) {
return;
}
draining = false;
if (currentQueue.length) {
queue = currentQueue.concat(queue);
} else {
queueIndex = -1;
}
if (queue.length) {
drainQueue();
}
}
function drainQueue() {
if (draining) {
return;
}
var timeout = runTimeout(cleanUpNextTick);
draining = true;
var len = queue.length;
while(len) {
currentQueue = queue;
queue = [];
while (++queueIndex < len) {
if (currentQueue) {
currentQueue[queueIndex].run();
}
}
queueIndex = -1;
len = queue.length;
}
currentQueue = null;
draining = false;
runClearTimeout(timeout);
}
process.nextTick = function (fun) {
var args = new Array(arguments.length - 1);
if (arguments.length > 1) {
for (var i = 1; i < arguments.length; i++) {
args[i - 1] = arguments[i];
}
}
queue.push(new Item(fun, args));
if (queue.length === 1 && !draining) {
runTimeout(drainQueue);
}
};
// v8 likes predictible objects
function Item(fun, array) {
this.fun = fun;
this.array = array;
}
Item.prototype.run = function () {
this.fun.apply(null, this.array);
};
process.title = 'browser';
process.browser = true;
process.env = {};
process.argv = [];
process.version = ''; // empty string to avoid regexp issues
process.versions = {};
function noop() {}
process.on = noop;
process.addListener = noop;
process.once = noop;
process.off = noop;
process.removeListener = noop;
process.removeAllListeners = noop;
process.emit = noop;
process.prependListener = noop;
process.prependOnceListener = noop;
process.listeners = function (name) { return [] }
process.binding = function (name) {
throw new Error('process.binding is not supported');
};
process.cwd = function () { return '/' };
process.chdir = function (dir) {
throw new Error('process.chdir is not supported');
};
process.umask = function() { return 0; };
},{}],36:[function(require,module,exports){
var grammar = module.exports = {
v: [{
name: 'version',
reg: /^(\d*)$/
}],
o: [{
// o=- 20518 0 IN IP4 203.0.113.1
// NB: sessionId will be a String in most cases because it is huge
name: 'origin',
reg: /^(\S*) (\d*) (\d*) (\S*) IP(\d) (\S*)/,
names: ['username', 'sessionId', 'sessionVersion', 'netType', 'ipVer', 'address'],
format: '%s %s %d %s IP%d %s'
}],
// default parsing of these only (though some of these feel outdated)
s: [{ name: 'name' }],
i: [{ name: 'description' }],
u: [{ name: 'uri' }],
e: [{ name: 'email' }],
p: [{ name: 'phone' }],
z: [{ name: 'timezones' }], // TODO: this one can actually be parsed properly...
r: [{ name: 'repeats' }], // TODO: this one can also be parsed properly
// k: [{}], // outdated thing ignored
t: [{
// t=0 0
name: 'timing',
reg: /^(\d*) (\d*)/,
names: ['start', 'stop'],
format: '%d %d'
}],
c: [{
// c=IN IP4 10.47.197.26
name: 'connection',
reg: /^IN IP(\d) (\S*)/,
names: ['version', 'ip'],
format: 'IN IP%d %s'
}],
b: [{
// b=AS:4000
push: 'bandwidth',
reg: /^(TIAS|AS|CT|RR|RS):(\d*)/,
names: ['type', 'limit'],
format: '%s:%s'
}],
m: [{
// m=video 51744 RTP/AVP 126 97 98 34 31
// NB: special - pushes to session
// TODO: rtp/fmtp should be filtered by the payloads found here?
reg: /^(\w*) (\d*) ([\w/]*)(?: (.*))?/,
names: ['type', 'port', 'protocol', 'payloads'],
format: '%s %d %s %s'
}],
a: [
{
// a=rtpmap:110 opus/48000/2
push: 'rtp',
reg: /^rtpmap:(\d*) ([\w\-.]*)(?:\s*\/(\d*)(?:\s*\/(\S*))?)?/,
names: ['payload', 'codec', 'rate', 'encoding'],
format: function (o) {
return (o.encoding)
? 'rtpmap:%d %s/%s/%s'
: o.rate
? 'rtpmap:%d %s/%s'
: 'rtpmap:%d %s';
}
},
{
// a=fmtp:108 profile-level-id=24;object=23;bitrate=64000
// a=fmtp:111 minptime=10; useinbandfec=1
push: 'fmtp',
reg: /^fmtp:(\d*) ([\S| ]*)/,
names: ['payload', 'config'],
format: 'fmtp:%d %s'
},
{
// a=control:streamid=0
name: 'control',
reg: /^control:(.*)/,
format: 'control:%s'
},
{
// a=rtcp:65179 IN IP4 193.84.77.194
name: 'rtcp',
reg: /^rtcp:(\d*)(?: (\S*) IP(\d) (\S*))?/,
names: ['port', 'netType', 'ipVer', 'address'],
format: function (o) {
return (o.address != null)
? 'rtcp:%d %s IP%d %s'
: 'rtcp:%d';
}
},
{
// a=rtcp-fb:98 trr-int 100
push: 'rtcpFbTrrInt',
reg: /^rtcp-fb:(\*|\d*) trr-int (\d*)/,
names: ['payload', 'value'],
format: 'rtcp-fb:%d trr-int %d'
},
{
// a=rtcp-fb:98 nack rpsi
push: 'rtcpFb',
reg: /^rtcp-fb:(\*|\d*) ([\w-_]*)(?: ([\w-_]*))?/,
names: ['payload', 'type', 'subtype'],
format: function (o) {
return (o.subtype != null)
? 'rtcp-fb:%s %s %s'
: 'rtcp-fb:%s %s';
}
},
{
// a=extmap:2 urn:ietf:params:rtp-hdrext:toffset
// a=extmap:1/recvonly URI-gps-string
// a=extmap:3 urn:ietf:params:rtp-hdrext:encrypt urn:ietf:params:rtp-hdrext:smpte-tc 25@600/24
push: 'ext',
reg: /^extmap:(\d+)(?:\/(\w+))?(?: (urn:ietf:params:rtp-hdrext:encrypt))? (\S*)(?: (\S*))?/,
names: ['value', 'direction', 'encrypt-uri', 'uri', 'config'],
format: function (o) {
return (
'extmap:%d' +
(o.direction ? '/%s' : '%v') +
(o['encrypt-uri'] ? ' %s' : '%v') +
' %s' +
(o.config ? ' %s' : '')
);
}
},
{
// a=extmap-allow-mixed
name: 'extmapAllowMixed',
reg: /^(extmap-allow-mixed)/
},
{
// a=crypto:1 AES_CM_128_HMAC_SHA1_80 inline:PS1uQCVeeCFCanVmcjkpPywjNWhcYD0mXXtxaVBR|2^20|1:32
push: 'crypto',
reg: /^crypto:(\d*) ([\w_]*) (\S*)(?: (\S*))?/,
names: ['id', 'suite', 'config', 'sessionConfig'],
format: function (o) {
return (o.sessionConfig != null)
? 'crypto:%d %s %s %s'
: 'crypto:%d %s %s';
}
},
{
// a=setup:actpass
name: 'setup',
reg: /^setup:(\w*)/,
format: 'setup:%s'
},
{
// a=connection:new
name: 'connectionType',
reg: /^connection:(new|existing)/,
format: 'connection:%s'
},
{
// a=mid:1
name: 'mid',
reg: /^mid:([^\s]*)/,
format: 'mid:%s'
},
{
// a=msid:0c8b064d-d807-43b4-b434-f92a889d8587 98178685-d409-46e0-8e16-7ef0db0db64a
name: 'msid',
reg: /^msid:(.*)/,
format: 'msid:%s'
},
{
// a=ptime:20
name: 'ptime',
reg: /^ptime:(\d*(?:\.\d*)*)/,
format: 'ptime:%d'
},
{
// a=maxptime:60
name: 'maxptime',
reg: /^maxptime:(\d*(?:\.\d*)*)/,
format: 'maxptime:%d'
},
{
// a=sendrecv
name: 'direction',
reg: /^(sendrecv|recvonly|sendonly|inactive)/
},
{
// a=ice-lite
name: 'icelite',
reg: /^(ice-lite)/
},
{
// a=ice-ufrag:F7gI
name: 'iceUfrag',
reg: /^ice-ufrag:(\S*)/,
format: 'ice-ufrag:%s'
},
{
// a=ice-pwd:x9cml/YzichV2+XlhiMu8g
name: 'icePwd',
reg: /^ice-pwd:(\S*)/,
format: 'ice-pwd:%s'
},
{
// a=fingerprint:SHA-1 00:11:22:33:44:55:66:77:88:99:AA:BB:CC:DD:EE:FF:00:11:22:33
name: 'fingerprint',
reg: /^fingerprint:(\S*) (\S*)/,
names: ['type', 'hash'],
format: 'fingerprint:%s %s'
},
{
// a=candidate:0 1 UDP 2113667327 203.0.113.1 54400 typ host
// a=candidate:1162875081 1 udp 2113937151 192.168.34.75 60017 typ host generation 0 network-id 3 network-cost 10
// a=candidate:3289912957 2 udp 1845501695 193.84.77.194 60017 typ srflx raddr 192.168.34.75 rport 60017 generation 0 network-id 3 network-cost 10
// a=candidate:229815620 1 tcp 1518280447 192.168.150.19 60017 typ host tcptype active generation 0 network-id 3 network-cost 10
// a=candidate:3289912957 2 tcp 1845501695 193.84.77.194 60017 typ srflx raddr 192.168.34.75 rport 60017 tcptype passive generation 0 network-id 3 network-cost 10
push:'candidates',
reg: /^candidate:(\S*) (\d*) (\S*) (\d*) (\S*) (\d*) typ (\S*)(?: raddr (\S*) rport (\d*))?(?: tcptype (\S*))?(?: generation (\d*))?(?: network-id (\d*))?(?: network-cost (\d*))?/,
names: ['foundation', 'component', 'transport', 'priority', 'ip', 'port', 'type', 'raddr', 'rport', 'tcptype', 'generation', 'network-id', 'network-cost'],
format: function (o) {
var str = 'candidate:%s %d %s %d %s %d typ %s';
str += (o.raddr != null) ? ' raddr %s rport %d' : '%v%v';
// NB: candidate has three optional chunks, so %void middles one if it's missing
str += (o.tcptype != null) ? ' tcptype %s' : '%v';
if (o.generation != null) {
str += ' generation %d';
}
str += (o['network-id'] != null) ? ' network-id %d' : '%v';
str += (o['network-cost'] != null) ? ' network-cost %d' : '%v';
return str;
}
},
{
// a=end-of-candidates (keep after the candidates line for readability)
name: 'endOfCandidates',
reg: /^(end-of-candidates)/
},
{
// a=remote-candidates:1 203.0.113.1 54400 2 203.0.113.1 54401 ...
name: 'remoteCandidates',
reg: /^remote-candidates:(.*)/,
format: 'remote-candidates:%s'
},
{
// a=ice-options:google-ice
name: 'iceOptions',
reg: /^ice-options:(\S*)/,
format: 'ice-options:%s'
},
{
// a=ssrc:2566107569 cname:t9YU8M1UxTF8Y1A1
push: 'ssrcs',
reg: /^ssrc:(\d*) ([\w_-]*)(?::(.*))?/,
names: ['id', 'attribute', 'value'],
format: function (o) {
var str = 'ssrc:%d';
if (o.attribute != null) {
str += ' %s';
if (o.value != null) {
str += ':%s';
}
}
return str;
}
},
{
// a=ssrc-group:FEC 1 2
// a=ssrc-group:FEC-FR 3004364195 1080772241
push: 'ssrcGroups',
// token-char = %x21 / %x23-27 / %x2A-2B / %x2D-2E / %x30-39 / %x41-5A / %x5E-7E
reg: /^ssrc-group:([\x21\x23\x24\x25\x26\x27\x2A\x2B\x2D\x2E\w]*) (.*)/,
names: ['semantics', 'ssrcs'],
format: 'ssrc-group:%s %s'
},
{
// a=msid-semantic: WMS Jvlam5X3SX1OP6pn20zWogvaKJz5Hjf9OnlV
name: 'msidSemantic',
reg: /^msid-semantic:\s?(\w*) (\S*)/,
names: ['semantic', 'token'],
format: 'msid-semantic: %s %s' // space after ':' is not accidental
},
{
// a=group:BUNDLE audio video
push: 'groups',
reg: /^group:(\w*) (.*)/,
names: ['type', 'mids'],
format: 'group:%s %s'
},
{
// a=rtcp-mux
name: 'rtcpMux',
reg: /^(rtcp-mux)/
},
{
// a=rtcp-rsize
name: 'rtcpRsize',
reg: /^(rtcp-rsize)/
},
{
// a=sctpmap:5000 webrtc-datachannel 1024
name: 'sctpmap',
reg: /^sctpmap:([\w_/]*) (\S*)(?: (\S*))?/,
names: ['sctpmapNumber', 'app', 'maxMessageSize'],
format: function (o) {
return (o.maxMessageSize != null)
? 'sctpmap:%s %s %s'
: 'sctpmap:%s %s';
}
},
{
// a=x-google-flag:conference
name: 'xGoogleFlag',
reg: /^x-google-flag:([^\s]*)/,
format: 'x-google-flag:%s'
},
{
// a=rid:1 send max-width=1280;max-height=720;max-fps=30;depend=0
push: 'rids',
reg: /^rid:([\d\w]+) (\w+)(?: ([\S| ]*))?/,
names: ['id', 'direction', 'params'],
format: function (o) {
return (o.params) ? 'rid:%s %s %s' : 'rid:%s %s';
}
},
{
// a=imageattr:97 send [x=800,y=640,sar=1.1,q=0.6] [x=480,y=320] recv [x=330,y=250]
// a=imageattr:* send [x=800,y=640] recv *
// a=imageattr:100 recv [x=320,y=240]
push: 'imageattrs',
reg: new RegExp(
// a=imageattr:97
'^imageattr:(\\d+|\\*)' +
// send [x=800,y=640,sar=1.1,q=0.6] [x=480,y=320]
'[\\s\\t]+(send|recv)[\\s\\t]+(\\*|\\[\\S+\\](?:[\\s\\t]+\\[\\S+\\])*)' +
// recv [x=330,y=250]
'(?:[\\s\\t]+(recv|send)[\\s\\t]+(\\*|\\[\\S+\\](?:[\\s\\t]+\\[\\S+\\])*))?'
),
names: ['pt', 'dir1', 'attrs1', 'dir2', 'attrs2'],
format: function (o) {
return 'imageattr:%s %s %s' + (o.dir2 ? ' %s %s' : '');
}
},
{
// a=simulcast:send 1,2,3;~4,~5 recv 6;~7,~8
// a=simulcast:recv 1;4,5 send 6;7
name: 'simulcast',
reg: new RegExp(
// a=simulcast:
'^simulcast:' +
// send 1,2,3;~4,~5
'(send|recv) ([a-zA-Z0-9\\-_~;,]+)' +
// space + recv 6;~7,~8
'(?:\\s?(send|recv) ([a-zA-Z0-9\\-_~;,]+))?' +
// end
'$'
),
names: ['dir1', 'list1', 'dir2', 'list2'],
format: function (o) {
return 'simulcast:%s %s' + (o.dir2 ? ' %s %s' : '');
}
},
{
// old simulcast draft 03 (implemented by Firefox)
// https://tools.ietf.org/html/draft-ietf-mmusic-sdp-simulcast-03
// a=simulcast: recv pt=97;98 send pt=97
// a=simulcast: send rid=5;6;7 paused=6,7
name: 'simulcast_03',
reg: /^simulcast:[\s\t]+([\S+\s\t]+)$/,
names: ['value'],
format: 'simulcast: %s'
},
{
// a=framerate:25
// a=framerate:29.97
name: 'framerate',
reg: /^framerate:(\d+(?:$|\.\d+))/,
format: 'framerate:%s'
},
{
// RFC4570
// a=source-filter: incl IN IP4 239.5.2.31 10.1.15.5
name: 'sourceFilter',
reg: /^source-filter: *(excl|incl) (\S*) (IP4|IP6|\*) (\S*) (.*)/,
names: ['filterMode', 'netType', 'addressTypes', 'destAddress', 'srcList'],
format: 'source-filter: %s %s %s %s %s'
},
{
// a=bundle-only
name: 'bundleOnly',
reg: /^(bundle-only)/
},
{
// a=label:1
name: 'label',
reg: /^label:(.+)/,
format: 'label:%s'
},
{
// RFC version 26 for SCTP over DTLS
// https://tools.ietf.org/html/draft-ietf-mmusic-sctp-sdp-26#section-5
name: 'sctpPort',
reg: /^sctp-port:(\d+)$/,
format: 'sctp-port:%s'
},
{
// RFC version 26 for SCTP over DTLS
// https://tools.ietf.org/html/draft-ietf-mmusic-sctp-sdp-26#section-6
name: 'maxMessageSize',
reg: /^max-message-size:(\d+)$/,
format: 'max-message-size:%s'
},
{
// RFC7273
// a=ts-refclk:ptp=IEEE1588-2008:39-A7-94-FF-FE-07-CB-D0:37
push:'tsRefClocks',
reg: /^ts-refclk:([^\s=]*)(?:=(\S*))?/,
names: ['clksrc', 'clksrcExt'],
format: function (o) {
return 'ts-refclk:%s' + (o.clksrcExt != null ? '=%s' : '');
}
},
{
// RFC7273
// a=mediaclk:direct=963214424
name:'mediaClk',
reg: /^mediaclk:(?:id=(\S*))? *([^\s=]*)(?:=(\S*))?(?: *rate=(\d+)\/(\d+))?/,
names: ['id', 'mediaClockName', 'mediaClockValue', 'rateNumerator', 'rateDenominator'],
format: function (o) {
var str = 'mediaclk:';
str += (o.id != null ? 'id=%s %s' : '%v%s');
str += (o.mediaClockValue != null ? '=%s' : '');
str += (o.rateNumerator != null ? ' rate=%s' : '');
str += (o.rateDenominator != null ? '/%s' : '');
return str;
}
},
{
// a=keywds:keywords
name: 'keywords',
reg: /^keywds:(.+)$/,
format: 'keywds:%s'
},
{
// a=content:main
name: 'content',
reg: /^content:(.+)/,
format: 'content:%s'
},
// BFCP https://tools.ietf.org/html/rfc4583
{
// a=floorctrl:c-s
name: 'bfcpFloorCtrl',
reg: /^floorctrl:(c-only|s-only|c-s)/,
format: 'floorctrl:%s'
},
{
// a=confid:1
name: 'bfcpConfId',
reg: /^confid:(\d+)/,
format: 'confid:%s'
},
{
// a=userid:1
name: 'bfcpUserId',
reg: /^userid:(\d+)/,
format: 'userid:%s'
},
{
// a=floorid:1
name: 'bfcpFloorId',
reg: /^floorid:(.+) (?:m-stream|mstrm):(.+)/,
names: ['id', 'mStream'],
format: 'floorid:%s mstrm:%s'
},
{
// any a= that we don't understand is kept verbatim on media.invalid
push: 'invalid',
names: ['value']
}
]
};
// set sensible defaults to avoid polluting the grammar with boring details
Object.keys(grammar).forEach(function (key) {
var objs = grammar[key];
objs.forEach(function (obj) {
if (!obj.reg) {
obj.reg = /(.*)/;
}
if (!obj.format) {
obj.format = '%s';
}
});
});
},{}],37:[function(require,module,exports){
var parser = require('./parser');
var writer = require('./writer');
exports.write = writer;
exports.parse = parser.parse;
exports.parseParams = parser.parseParams;
exports.parseFmtpConfig = parser.parseFmtpConfig; // Alias of parseParams().
exports.parsePayloads = parser.parsePayloads;
exports.parseRemoteCandidates = parser.parseRemoteCandidates;
exports.parseImageAttributes = parser.parseImageAttributes;
exports.parseSimulcastStreamList = parser.parseSimulcastStreamList;
},{"./parser":38,"./writer":39}],38:[function(require,module,exports){
var toIntIfInt = function (v) {
return String(Number(v)) === v ? Number(v) : v;
};
var attachProperties = function (match, location, names, rawName) {
if (rawName && !names) {
location[rawName] = toIntIfInt(match[1]);
}
else {
for (var i = 0; i < names.length; i += 1) {
if (match[i+1] != null) {
location[names[i]] = toIntIfInt(match[i+1]);
}
}
}
};
var parseReg = function (obj, location, content) {
var needsBlank = obj.name && obj.names;
if (obj.push && !location[obj.push]) {
location[obj.push] = [];
}
else if (needsBlank && !location[obj.name]) {
location[obj.name] = {};
}
var keyLocation = obj.push ?
{} : // blank object that will be pushed
needsBlank ? location[obj.name] : location; // otherwise, named location or root
attachProperties(content.match(obj.reg), keyLocation, obj.names, obj.name);
if (obj.push) {
location[obj.push].push(keyLocation);
}
};
var grammar = require('./grammar');
var validLine = RegExp.prototype.test.bind(/^([a-z])=(.*)/);
exports.parse = function (sdp) {
var session = {}
, media = []
, location = session; // points at where properties go under (one of the above)
// parse lines we understand
sdp.split(/(\r\n|\r|\n)/).filter(validLine).forEach(function (l) {
var type = l[0];
var content = l.slice(2);
if (type === 'm') {
media.push({rtp: [], fmtp: []});
location = media[media.length-1]; // point at latest media line
}
for (var j = 0; j < (grammar[type] || []).length; j += 1) {
var obj = grammar[type][j];
if (obj.reg.test(content)) {
return parseReg(obj, location, content);
}
}
});
session.media = media; // link it up
return session;
};
var paramReducer = function (acc, expr) {
var s = expr.split(/=(.+)/, 2);
if (s.length === 2) {
acc[s[0]] = toIntIfInt(s[1]);
} else if (s.length === 1 && expr.length > 1) {
acc[s[0]] = undefined;
}
return acc;
};
exports.parseParams = function (str) {
return str.split(/;\s?/).reduce(paramReducer, {});
};
// For backward compatibility - alias will be removed in 3.0.0
exports.parseFmtpConfig = exports.parseParams;
exports.parsePayloads = function (str) {
return str.toString().split(' ').map(Number);
};
exports.parseRemoteCandidates = function (str) {
var candidates = [];
var parts = str.split(' ').map(toIntIfInt);
for (var i = 0; i < parts.length; i += 3) {
candidates.push({
component: parts[i],
ip: parts[i + 1],
port: parts[i + 2]
});
}
return candidates;
};
exports.parseImageAttributes = function (str) {
return str.split(' ').map(function (item) {
return item.substring(1, item.length-1).split(',').reduce(paramReducer, {});
});
};
exports.parseSimulcastStreamList = function (str) {
return str.split(';').map(function (stream) {
return stream.split(',').map(function (format) {
var scid, paused = false;
if (format[0] !== '~') {
scid = toIntIfInt(format);
} else {
scid = toIntIfInt(format.substring(1, format.length));
paused = true;
}
return {
scid: scid,
paused: paused
};
});
});
};
},{"./grammar":36}],39:[function(require,module,exports){
var grammar = require('./grammar');
// customized util.format - discards excess arguments and can void middle ones
var formatRegExp = /%[sdv%]/g;
var format = function (formatStr) {
var i = 1;
var args = arguments;
var len = args.length;
return formatStr.replace(formatRegExp, function (x) {
if (i >= len) {
return x; // missing argument
}
var arg = args[i];
i += 1;
switch (x) {
case '%%':
return '%';
case '%s':
return String(arg);
case '%d':
return Number(arg);
case '%v':
return '';
}
});
// NB: we discard excess arguments - they are typically undefined from makeLine
};
var makeLine = function (type, obj, location) {
var str = obj.format instanceof Function ?
(obj.format(obj.push ? location : location[obj.name])) :
obj.format;
var args = [type + '=' + str];
if (obj.names) {
for (var i = 0; i < obj.names.length; i += 1) {
var n = obj.names[i];
if (obj.name) {
args.push(location[obj.name][n]);
}
else { // for mLine and push attributes
args.push(location[obj.names[i]]);
}
}
}
else {
args.push(location[obj.name]);
}
return format.apply(null, args);
};
// RFC specified order
// TODO: extend this with all the rest
var defaultOuterOrder = [
'v', 'o', 's', 'i',
'u', 'e', 'p', 'c',
'b', 't', 'r', 'z', 'a'
];
var defaultInnerOrder = ['i', 'c', 'b', 'a'];
module.exports = function (session, opts) {
opts = opts || {};
// ensure certain properties exist
if (session.version == null) {
session.version = 0; // 'v=0' must be there (only defined version atm)
}
if (session.name == null) {
session.name = ' '; // 's= ' must be there if no meaningful name set
}
session.media.forEach(function (mLine) {
if (mLine.payloads == null) {
mLine.payloads = '';
}
});
var outerOrder = opts.outerOrder || defaultOuterOrder;
var innerOrder = opts.innerOrder || defaultInnerOrder;
var sdp = [];
// loop through outerOrder for matching properties on session
outerOrder.forEach(function (type) {
grammar[type].forEach(function (obj) {
if (obj.name in session && session[obj.name] != null) {
sdp.push(makeLine(type, obj, session));
}
else if (obj.push in session && session[obj.push] != null) {
session[obj.push].forEach(function (el) {
sdp.push(makeLine(type, obj, el));
});
}
});
});
// then for each media line, follow the innerOrder
session.media.forEach(function (mLine) {
sdp.push(makeLine('m', grammar.m[0], mLine));
innerOrder.forEach(function (type) {
grammar[type].forEach(function (obj) {
if (obj.name in mLine && mLine[obj.name] != null) {
sdp.push(makeLine(type, obj, mLine));
}
else if (obj.push in mLine && mLine[obj.push] != null) {
mLine[obj.push].forEach(function (el) {
sdp.push(makeLine(type, obj, el));
});
}
});
});
});
return sdp.join('\r\n') + '\r\n';
};
},{"./grammar":36}],40:[function(require,module,exports){
module.exports={
"name": "SimpleSIP",
"title": "SimpleSIP",
"description": "the Javascript SIP library",
"version": "3.10.1",
"homepage": "https://SimpleSIP.net",
"contributors": [
"José Luis Millán <jmillan@aliax.net> (https://github.com/jmillan)",
"Iñaki Baz Castillo <ibc@aliax.net> (https://inakibaz.me)"
],
"types": "lib/SimpleSIP.d.ts",
"main": "lib-es5/SimpleSIP.js",
"keywords": [
"sip",
"websocket",
"webrtc",
"node",
"browser",
"library"
],
"license": "MIT",
"repository": {
"type": "git",
"url": "https://github.com/versatica/SimpleSIP.git"
},
"bugs": {
"url": "https://github.com/versatica/SimpleSIP/issues"
},
"dependencies": {
"@types/events": "^3.0.0",
"@types/debug": "^4.1.7",
"debug": "^4.3.1",
"events": "^3.3.0",
"sdp-transform": "^2.14.1"
},
"devDependencies": {
"@babel/core": "^7.19.6",
"@babel/preset-env": "^7.19.4",
"ansi-colors": "^3.2.4",
"browserify": "^16.5.1",
"eslint": "^5.16.0",
"fancy-log": "^1.3.3",
"gulp": "^4.0.2",
"gulp-babel": "^8.0.0",
"gulp-eslint": "^5.0.0",
"gulp-expect-file": "^1.0.2",
"gulp-header": "^2.0.9",
"gulp-nodeunit-runner": "^0.2.2",
"gulp-plumber": "^1.2.1",
"gulp-rename": "^1.4.0",
"gulp-uglify-es": "^1.0.4",
"pegjs": "^0.7.0",
"vinyl-buffer": "^1.0.1",
"vinyl-source-stream": "^2.0.0"
},
"scripts": {
"lint": "node npm-scripts.js lint",
"test": "node npm-scripts.js test",
"prepublish": "node npm-scripts.js prepublish",
"release": "node npm-scripts.js release"
}
}
},{}]},{},[8])(8)
});