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

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  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.info('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.log('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.log('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.
  90. *
  91. * @param {string} sipAddress - The sip address to use.
  92. * @param {string} displayName - The display name to use.
  93. * @returns {JitsiVideoSIPGWSession}
  94. */
  95. createVideoSIPGWSession(sipAddress, displayName) {
  96. const session = new JitsiVideoSIPGWSession(
  97. sipAddress, displayName, this.chatRoom);
  98. session.addStateListener(this.sessionStateChangeListener);
  99. if (this.sessions[sipAddress]) {
  100. logger.warn('There was already a Video SIP GW session for address',
  101. sipAddress);
  102. }
  103. this.sessions[sipAddress] = session;
  104. return session;
  105. }
  106. /**
  107. * Returns whether SIP GW service is available.
  108. *
  109. * @returns {boolean} whether SIP GW service is available.
  110. */
  111. isVideoSIPGWAvailable() {
  112. return this.status === Constants.STATUS_AVAILABLE;
  113. }
  114. /**
  115. * Listener for session state changed. When a session goes to off or failed
  116. * we delete its reference.
  117. *
  118. * @param {string} address - The SIP address of the session.
  119. * @param {options} event - { name, oldState, newState }
  120. */
  121. sessionStateChanged(address, event) {
  122. if (event.newState === Constants.STATE_OFF
  123. || event.newState === Constants.STATE_FAILED) {
  124. const session = this.sessions[address];
  125. if (!session) {
  126. logger.error('Missing Video SIP GW session with address:',
  127. address);
  128. return;
  129. }
  130. session.removeStateListener(this.sessionStateChangeListener);
  131. delete this.sessions[address];
  132. }
  133. }
  134. }