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.

VideoSIPGW.js 4.8KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161
  1. import { getLogger } from 'jitsi-meet-logger';
  2. const logger = getLogger(__filename);
  3. import JitsiVideoSIPGWSession from './JitsiVideoSIPGWSession';
  4. import * as Constants from './VideoSIPGWConstants';
  5. import XMPPEvents from '../../service/xmpp/XMPPEvents';
  6. /**
  7. * Main video SIP GW handler. Stores references of all created sessions.
  8. */
  9. export default class VideoSIPGW {
  10. /**
  11. * Creates new handler.
  12. *
  13. * @param {ChatRoom} chatRoom - Tha chat room to handle.
  14. */
  15. constructor(chatRoom) {
  16. this.chatRoom = chatRoom;
  17. this.eventEmitter = chatRoom.eventEmitter;
  18. logger.debug('creating VideoSIPGW');
  19. this.sessions = {};
  20. this.sessionStateChangeListener = this.sessionStateChanged.bind(this);
  21. // VideoSIPGW, JitsiConference and ChatRoom are not reusable and no
  22. // more than one VideoSIPGW can be created per JitsiConference,
  23. // so we don't bother to cleanup
  24. chatRoom.addPresenceListener('jibri-sip-status',
  25. this.handleJibriSIPStatus.bind(this));
  26. chatRoom.addPresenceListener('jibri-sip-call-state',
  27. this.handleJibriSIPState.bind(this));
  28. }
  29. /**
  30. * Handles presence nodes with name: jibri-sip-status.
  31. *
  32. * @param {Object} node the presence node Object to handle.
  33. * Object representing part of the presence received over xmpp.
  34. */
  35. handleJibriSIPStatus(node) {
  36. const attributes = node.attributes;
  37. if (!attributes) {
  38. return;
  39. }
  40. logger.debug('Handle video sip gw status : ', attributes);
  41. const newStatus = attributes.status;
  42. // check for global availability of the service
  43. if (newStatus !== this.status
  44. && (newStatus === Constants.STATUS_UNDEFINED
  45. || newStatus === Constants.STATUS_AVAILABLE
  46. || newStatus === Constants.STATUS_BUSY)) {
  47. this.status = newStatus;
  48. this.eventEmitter.emit(
  49. XMPPEvents.VIDEO_SIP_GW_AVAILABILITY_CHANGED, this.status);
  50. }
  51. }
  52. /**
  53. * Handles presence nodes with name: jibri-sip-call-state.
  54. *
  55. * @param {Object} node the presence node Object to handle.
  56. * Object representing part of the presence received over xmpp.
  57. */
  58. handleJibriSIPState(node) {
  59. const attributes = node.attributes;
  60. if (!attributes) {
  61. return;
  62. }
  63. logger.debug('Handle video sip gw state : ', attributes);
  64. const newState = attributes.state;
  65. if (newState === this.state) {
  66. return;
  67. }
  68. switch (newState) {
  69. case Constants.STATE_ON:
  70. case Constants.STATE_OFF:
  71. case Constants.STATE_PENDING:
  72. case Constants.STATE_RETRYING:
  73. case Constants.STATE_FAILED: {
  74. const address = attributes.sipaddress;
  75. if (!address) {
  76. return;
  77. }
  78. // find the corresponding session and set its state
  79. const session = this.sessions[address];
  80. if (session) {
  81. session.setState(newState);
  82. } else {
  83. logger.warn('Video SIP GW session not found:', address);
  84. }
  85. }
  86. }
  87. }
  88. /**
  89. * Creates new session and stores its reference if it does not exist or
  90. * returns an error otherwise.
  91. *
  92. * @param {string} sipAddress - The sip address to use.
  93. * @param {string} displayName - The display name to use.
  94. * @returns {JitsiVideoSIPGWSession|Error}
  95. */
  96. createVideoSIPGWSession(sipAddress, displayName) {
  97. if (this.sessions[sipAddress]) {
  98. logger.warn('There was already a Video SIP GW session for address',
  99. sipAddress);
  100. return new Error(Constants.ERROR_SESSION_EXISTS);
  101. }
  102. const session = new JitsiVideoSIPGWSession(
  103. sipAddress, displayName, this.chatRoom);
  104. session.addStateListener(this.sessionStateChangeListener);
  105. this.sessions[sipAddress] = session;
  106. return session;
  107. }
  108. /**
  109. * Listener for session state changed. When a session goes to off or failed
  110. * we delete its reference.
  111. *
  112. * @param {options} event - { address, oldState, newState, displayName }
  113. */
  114. sessionStateChanged(event) {
  115. const address = event.address;
  116. if (event.newState === Constants.STATE_OFF
  117. || event.newState === Constants.STATE_FAILED) {
  118. const session = this.sessions[address];
  119. if (!session) {
  120. logger.error('Missing Video SIP GW session with address:',
  121. address);
  122. return;
  123. }
  124. session.removeStateListener(this.sessionStateChangeListener);
  125. delete this.sessions[address];
  126. }
  127. this.eventEmitter.emit(
  128. XMPPEvents.VIDEO_SIP_GW_SESSION_STATE_CHANGED,
  129. event);
  130. }
  131. }