Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
9 changed files
with
276 additions
and
33 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
/** | ||
* The type of (redux) action which signals that sip GW service change its | ||
* availability status. | ||
* | ||
* { | ||
* type: SIP_GW_AVAILABILITY_CHANGED, | ||
* status: string | ||
* } | ||
*/ | ||
export const SIP_GW_AVAILABILITY_CHANGED | ||
= Symbol('SIP_GW_AVAILABILITY_CHANGED'); | ||
|
||
/** | ||
* The type of the action which signals to invite room participants to the | ||
* conference through the SIP Jibri service. | ||
* | ||
* { | ||
* type: SIP_GW_INVITE_ROOMS, | ||
* conference: JitsiConference, | ||
* rooms: {Immutable.List} | ||
* } | ||
*/ | ||
export const SIP_GW_INVITE_ROOMS = Symbol('SIP_GW_INVITE_ROOMS'); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
/* @flow */ | ||
|
||
import { SIP_GW_INVITE_ROOMS } from './actionTypes'; | ||
|
||
/** | ||
* Invites room participants to the conference through the SIP Jibri service. | ||
* | ||
* @param {JitsiMeetConference} conference - The conference to which the rooms | ||
* will be invited to. | ||
* @param {Immutable.List} rooms - The list of the "videosipgw" type items to | ||
* invite. | ||
* @returns {void} | ||
*/ | ||
export function inviteRooms( | ||
conference: Object, | ||
rooms: Object) { | ||
return { | ||
type: SIP_GW_INVITE_ROOMS, | ||
conference, | ||
rooms | ||
}; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
export * from './actions'; | ||
|
||
import './middleware'; | ||
import './reducer'; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,182 @@ | ||
/* @flow */ | ||
|
||
import Logger from 'jitsi-meet-logger'; | ||
import { CONFERENCE_WILL_JOIN } from '../base/conference'; | ||
import { | ||
SIP_GW_AVAILABILITY_CHANGED, | ||
SIP_GW_INVITE_ROOMS | ||
} from './actionTypes'; | ||
import { | ||
JitsiConferenceEvents, | ||
JitsiSIPVideoGWStatus | ||
} from '../base/lib-jitsi-meet'; | ||
import { MiddlewareRegistry } from '../base/redux'; | ||
import { | ||
Notification, | ||
showErrorNotification, | ||
showNotification, | ||
showWarningNotification | ||
} from '../notifications'; | ||
|
||
const logger = Logger.getLogger(__filename); | ||
|
||
/** | ||
* Middleware that captures conference video sip gw events and stores | ||
* the global sip gw availability in redux or show appropriate notification | ||
* for sip gw sessions. | ||
* Captures invitation actions that create sip gw sessions or display | ||
* appropriate error/warning notifications. | ||
* | ||
* @param {Store} store - The redux store. | ||
* @returns {Function} | ||
*/ | ||
MiddlewareRegistry.register(({ dispatch, getState }) => next => action => { | ||
const result = next(action); | ||
|
||
switch (action.type) { | ||
case CONFERENCE_WILL_JOIN: { | ||
const conference = getState()['features/base/conference'].joining; | ||
|
||
conference.on( | ||
JitsiConferenceEvents.VIDEO_SIP_GW_AVAILABILITY_CHANGED, | ||
(...args) => dispatch(_availabilityChanged(...args))); | ||
conference.on( | ||
JitsiConferenceEvents.VIDEO_SIP_GW_SESSION_STATE_CHANGED, | ||
event => { | ||
const toDispatch = _sessionStateChanged(event); | ||
|
||
// sessionStateChanged can decide there is nothing to dispatch | ||
if (toDispatch) { | ||
dispatch(toDispatch); | ||
} | ||
}); | ||
|
||
break; | ||
} | ||
case SIP_GW_INVITE_ROOMS: { | ||
const { status } = getState()['features/videosipgw']; | ||
|
||
if (status === JitsiSIPVideoGWStatus.STATUS_UNDEFINED) { | ||
dispatch(showErrorNotification({ | ||
descriptionKey: 'recording.unavailable', | ||
descriptionArguments: { | ||
serviceName: '$t(videoSIPGW.serviceName)' | ||
}, | ||
titleKey: 'videoSIPGW.unavailableTitle' | ||
})); | ||
|
||
return; | ||
} else if (status === JitsiSIPVideoGWStatus.STATUS_BUSY) { | ||
dispatch(showWarningNotification({ | ||
descriptionKey: 'videoSIPGW.busy', | ||
titleKey: 'videoSIPGW.busyTitle' | ||
})); | ||
|
||
return; | ||
} else if (status !== JitsiSIPVideoGWStatus.STATUS_AVAILABLE) { | ||
logger.error(`Unknown sip videogw status ${status}`); | ||
|
||
return; | ||
} | ||
|
||
for (const room of action.rooms) { | ||
const { id: sipAddress, name: displayName } = room; | ||
|
||
if (sipAddress && displayName) { | ||
const newSession = action.conference | ||
.createVideoSIPGWSession(sipAddress, displayName); | ||
|
||
if (newSession instanceof Error) { | ||
const e = newSession; | ||
|
||
if (e) { | ||
switch (e.message) { | ||
case JitsiSIPVideoGWStatus.ERROR_NO_CONNECTION: { | ||
dispatch(showErrorNotification({ | ||
descriptionKey: 'videoSIPGW.errorInvite', | ||
titleKey: 'videoSIPGW.errorInviteTitle' | ||
})); | ||
|
||
return; | ||
} | ||
case JitsiSIPVideoGWStatus.ERROR_SESSION_EXISTS: { | ||
dispatch(showWarningNotification({ | ||
titleKey: 'videoSIPGW.errorAlreadyInvited', | ||
titleArguments: { displayName } | ||
})); | ||
|
||
return; | ||
} | ||
} | ||
} | ||
logger.error( | ||
'Unknown error trying to create sip videogw session', | ||
e); | ||
|
||
return; | ||
} | ||
|
||
newSession.start(); | ||
} else { | ||
logger.error(`No display name or sip number for ${ | ||
JSON.stringify(room)}`); | ||
} | ||
} | ||
} | ||
} | ||
|
||
return result; | ||
}); | ||
|
||
/** | ||
* Signals that sip gw availability had changed. | ||
* | ||
* @param {string} status - The new status of the service. | ||
* @returns {{ | ||
* type: SIP_GW_AVAILABILITY_CHANGED, | ||
* status: string | ||
* }} | ||
* @private | ||
*/ | ||
function _availabilityChanged(status: string) { | ||
return { | ||
type: SIP_GW_AVAILABILITY_CHANGED, | ||
status | ||
}; | ||
} | ||
|
||
/** | ||
* Signals that a session we created has a change in its status. | ||
* | ||
* @param {string} event - The event describing the session state change. | ||
* @returns {{ | ||
* type: SHOW_NOTIFICATION | ||
* }}|null | ||
* @private | ||
*/ | ||
function _sessionStateChanged( | ||
event: Object) { | ||
switch (event.newState) { | ||
case JitsiSIPVideoGWStatus.STATE_PENDING: { | ||
return showNotification( | ||
Notification, { | ||
titleKey: 'videoSIPGW.pending', | ||
titleArguments: { | ||
displayName: event.displayName | ||
} | ||
}, 2000); | ||
} | ||
case JitsiSIPVideoGWStatus.STATE_FAILED: { | ||
return showErrorNotification({ | ||
titleKey: 'videoSIPGW.errorInviteFailedTitle', | ||
titleArguments: { | ||
displayName: event.displayName | ||
}, | ||
descriptionKey: 'videoSIPGW.errorInviteFailed' | ||
}); | ||
} | ||
} | ||
|
||
// nothing to show | ||
return null; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
import { ReducerRegistry } from '../base/redux'; | ||
|
||
import { SIP_GW_AVAILABILITY_CHANGED } from './actionTypes'; | ||
|
||
ReducerRegistry.register( | ||
'features/videosipgw', (state = [], action) => { | ||
switch (action.type) { | ||
case SIP_GW_AVAILABILITY_CHANGED: { | ||
return { | ||
...state, | ||
status: action.status | ||
}; | ||
} | ||
} | ||
|
||
return state; | ||
}); |