UNPKG

jssip

Version:

The Javascript SIP library

127 lines (126 loc) 4.65 kB
"use strict"; const EventEmitter = require('events').EventEmitter; const Logger = require('../Logger'); const JsSIP_C = require('../Constants'); const Grammar = require('../Grammar'); const Utils = require('../Utils'); const logger = new Logger('RTCSession:ReferSubscriber'); module.exports = class ReferSubscriber extends EventEmitter { constructor(session) { super(); this._id = null; this._session = session; } get id() { return this._id; } sendRefer(target, options = {}) { logger.debug('sendRefer()'); const extraHeaders = Utils.cloneArray(options.extraHeaders); const eventHandlers = Utils.cloneObject(options.eventHandlers); // Set event handlers. for (const event in eventHandlers) { if (Object.prototype.hasOwnProperty.call(eventHandlers, event)) { this.on(event, eventHandlers[event]); } } // Replaces URI header field. let replaces = null; if (options.replaces) { replaces = options.replaces._request.call_id; replaces += `;to-tag=${options.replaces._to_tag}`; replaces += `;from-tag=${options.replaces._from_tag}`; replaces = encodeURIComponent(replaces); } // Refer-To header field. const referTo = `Refer-To: <${target}${replaces ? `?Replaces=${replaces}` : ''}>`; extraHeaders.push(referTo); // Referred-By header field (if not already present). if (!extraHeaders.some(header => header.toLowerCase().startsWith('referred-by:'))) { const referredBy = `Referred-By: <${this._session._ua._configuration.uri._scheme}:${this._session._ua._configuration.uri._user}@${this._session._ua._configuration.uri._host}>`; extraHeaders.push(referredBy); } extraHeaders.push(`Contact: ${this._session.contact}`); const request = this._session.sendRequest(JsSIP_C.REFER, { extraHeaders, eventHandlers: { onSuccessResponse: response => { this._requestSucceeded(response); }, onErrorResponse: response => { this._requestFailed(response, JsSIP_C.causes.REJECTED); }, onTransportError: () => { this._requestFailed(null, JsSIP_C.causes.CONNECTION_ERROR); }, onRequestTimeout: () => { this._requestFailed(null, JsSIP_C.causes.REQUEST_TIMEOUT); }, onDialogError: () => { this._requestFailed(null, JsSIP_C.causes.DIALOG_ERROR); }, onAuthenticated: _request => { this._id = _request.cseq; this.emit('authenticated'); }, }, }); this._id = request.cseq; } receiveNotify(request) { logger.debug('receiveNotify()'); if (!request.body) { return; } const 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: "${request.body}"`); return; } switch (true) { case /^100$/.test(status_line.status_code): { this.emit('trying', { request, status_line, }); break; } case /^1[0-9]{2}$/.test(status_line.status_code): { this.emit('progress', { request, status_line, }); break; } case /^2[0-9]{2}$/.test(status_line.status_code): { this.emit('accepted', { request, status_line, }); break; } default: { this.emit('failed', { request, status_line, }); break; } } } _requestSucceeded(response) { logger.debug('REFER succeeded'); logger.debug('emit "requestSucceeded"'); this.emit('requestSucceeded', { response, }); } _requestFailed(response, cause) { logger.debug('REFER failed'); logger.debug('emit "requestFailed"'); this.emit('requestFailed', { response: response || null, cause, }); } };