Source: RTCSession/Request.js

module.exports = Request;

/**
 * Dependencies.
 */
var JsSIP_C = require('../Constants');
var EventEmitter = require('../EventEmitter');
var Exceptions = require('../Exceptions');
var RTCSession = require('../RTCSession');
var Utils = require('../Utils');


function Request(session) {
  var events = [
    'progress',
    'succeeded',
    'failed'
  ];

  this.owner = session;

  this.initEvents(events);
}


Request.prototype = new EventEmitter();


Request.prototype.send = function(method, options) {
  options = options || {};

  var event,
    extraHeaders = options.extraHeaders && options.extraHeaders.slice() || [],
    eventHandlers = options.eventHandlers || {},
    body = options.body || null;

  if (method === undefined) {
    throw new TypeError('Not enough arguments');
  }

  // Check RTCSession Status
  if (this.owner.status !== RTCSession.C.STATUS_1XX_RECEIVED &&
    this.owner.status !== RTCSession.C.STATUS_WAITING_FOR_ANSWER &&
    this.owner.status !== RTCSession.C.STATUS_WAITING_FOR_ACK &&
    this.owner.status !== RTCSession.C.STATUS_CONFIRMED &&
    this.owner.status !== RTCSession.C.STATUS_TERMINATED) {
    throw new Exceptions.InvalidStateError(this.owner.status);
  }

  /*
   * Allow sending BYE in TERMINATED status since the RTCSession
   * could had been terminated before the ACK had arrived.
   * RFC3261 Section 15, Paragraph 2
   */
  else if (this.owner.status === RTCSession.C.STATUS_TERMINATED && method !== JsSIP_C.BYE) {
    throw new Exceptions.InvalidStateError(this.owner.status);
  }

  // Set event handlers
  for (event in eventHandlers) {
    this.on(event, eventHandlers[event]);
  }

  this.owner.dialog.sendRequest(this, method, {
    extraHeaders: extraHeaders,
    body: body
  });
};

Request.prototype.receiveResponse = function(response) {
  var cause;

  switch(true) {
    case /^1[0-9]{2}$/.test(response.status_code):
      this.emit('progress', this, {
        originator: 'remote',
        response: response
      });
      break;

    case /^2[0-9]{2}$/.test(response.status_code):
      this.emit('succeeded', this, {
        originator: 'remote',
        response: response
      });
      break;

    default:
      cause = Utils.sipErrorCause(response.status_code);
      this.emit('failed', this, {
        originator: 'remote',
        response: response,
        cause: cause
      });
      break;
  }
};

Request.prototype.onRequestTimeout = function() {
  this.emit('failed', this, {
    originator: 'system',
    cause: JsSIP_C.causes.REQUEST_TIMEOUT
  });
  this.owner.onRequestTimeout();
};

Request.prototype.onTransportError = function() {
  this.emit('failed', this, {
    originator: 'system',
    cause: JsSIP_C.causes.CONNECTION_ERROR
  });
  this.owner.onTransportError();
};

Request.prototype.onDialogError = function(response) {
  this.emit('failed', this, {
    originator: 'remote',
    response: response,
    cause: JsSIP_C.causes.DIALOG_ERROR
  });
  this.owner.onDialogError(response);
};