UNPKG

jssip

Version:

the Javascript SIP library

169 lines (136 loc) 3.9 kB
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); } } }); 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 }); } };