diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/UsersApp.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/UsersApp.scala index d6414a1b3e2e8f77502686ed377f8ddfa2bedd39..4b3087ec946ec4400f364d86b2f93f151a99a2f7 100755 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/UsersApp.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/UsersApp.scala @@ -420,7 +420,8 @@ trait UsersApp { } def handleUserJoinedVoiceFromPhone(msg: UserJoinedVoiceConfMessage) = { - log.info("User joining from phone. meetingId=" + props.meetingProp.intId + " userId=" + msg.userId + " extUserId=" + msg.externUserId) + log.info("User joining from phone. meetingId=" + props.meetingProp.intId + " userId=" + msg.userId + + " extUserId=" + msg.externUserId) Users.getUserWithVoiceUserId(msg.voiceUserId, liveMeeting.users) match { case Some(user) => { diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/models/RegisteredUsers.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/models/RegisteredUsers.scala index 3c3874ccd8a78c6fdfeb1df4df5afe49835289a4..81f14bf67227b65f13200925272a2993e11cdc31 100755 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/models/RegisteredUsers.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/models/RegisteredUsers.scala @@ -63,14 +63,7 @@ class RegisteredUsers { } } -case class RegisteredUser( - id: String, - externId: String, - name: String, - role: String, - authToken: String, - avatarURL: String, - guest: Boolean, - authed: Boolean, - waitingForAcceptance: Boolean) +case class RegisteredUser(id: String, externId: String, name: String, role: String, + authToken: String, avatarURL: String, guest: Boolean, + authed: Boolean, waitingForAcceptance: Boolean) diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/models/UsersStatus.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/models/UsersStatus.scala new file mode 100755 index 0000000000000000000000000000000000000000..64a2e8558e40b61d6a102be1d01b1a1a680d8c65 --- /dev/null +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/models/UsersStatus.scala @@ -0,0 +1,65 @@ +package org.bigbluebutton.core.models + +import com.softwaremill.quicklens.modify + +object UsersStatus { + def findWithId(users: UsersStatus, userId: String): Option[UserStatus] = users.toVector.find(u => u.id == userId) + def findModerators(users: UsersStatus): Vector[UserStatus] = users.toVector.filter(u => u.role == Roles.MODERATOR_ROLE) + def findPresenters(users: UsersStatus): Vector[UserStatus] = users.toVector.filter(u => u.role == Roles.PRESENTER_ROLE) + def findViewers(users: UsersStatus): Vector[UserStatus] = users.toVector.filter(u => u.role == Roles.VIEWER_ROLE) + def hasModerator(users: UsersStatus): Boolean = users.toVector.filter(u => u.role == Roles.MODERATOR_ROLE).length > 0 + def hasPresenter(users: UsersStatus): Boolean = users.toVector.filter(u => u.role == Roles.PRESENTER_ROLE).length > 0 + def hasNoPresenter(users: UsersStatus): Boolean = users.toVector.filter(u => u.role == Roles.PRESENTER_ROLE).length == 0 + + def hasUserWithId(users: UsersStatus, id: String): Boolean = { + findWithId(users, id) match { + case Some(u) => true + case None => false + } + } + def numUsers(users: UsersStatus): Int = users.toVector.size + + def usersWhoAreNotPresenter(users: UsersStatus): Vector[UserStatus] = users.toVector filter (u => u.presenter == false) + + def unbecomePresenter(users: UsersStatus, userId: String) = { + for { + u <- findWithId(users, userId) + user = modify(u)(_.presenter).setTo(false) + } yield users.save(user) + } + + def becomePresenter(users: UsersStatus, userId: String) = { + for { + u <- findWithId(users, userId) + user = modify(u)(_.presenter).setTo(true) + } yield users.save(user) + } + + def isModerator(id: String, users: Users): Boolean = { + Users.findWithId(id, users) match { + case Some(user) => return user.role == Roles.MODERATOR_ROLE && !user.waitingForAcceptance + case None => return false + } + } +} + +class UsersStatus { + private var usersStatus: collection.immutable.HashMap[String, UserStatus] = new collection.immutable.HashMap[String, UserStatus] + + private def toVector: Vector[UserStatus] = usersStatus.values.toVector + + private def save(user: UserStatus): UserStatus = { + usersStatus += user.id -> user + user + } + + private def remove(id: String): Option[UserStatus] = { + val user = usersStatus.get(id) + user foreach (u => usersStatus -= id) + user + } +} + +case class UserStatus(id: String, externalId: String, name: String, role: String, + guest: Boolean, authed: Boolean, waitingForAcceptance: Boolean, emoji: String, + presenter: Boolean, avatar: String) diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/models/VoiceUsers.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/models/VoiceUsers.scala new file mode 100755 index 0000000000000000000000000000000000000000..f15fa1ddf30aa022eed1ea921433db55d476a8e4 --- /dev/null +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/models/VoiceUsers.scala @@ -0,0 +1,28 @@ +package org.bigbluebutton.core.models + +object VoiceUsers { + def findUserWithVoiceUserId(users: VoiceUsers, voiceUserId: String): Option[VoiceUser2x] = { + users.toVector find (u => u.id == voiceUserId) + } + +} + +class VoiceUsers { + private var users: collection.immutable.HashMap[String, VoiceUser2x] = + new collection.immutable.HashMap[String, VoiceUser2x] + + private def toVector: Vector[VoiceUser2x] = users.values.toVector + + private def save(user: VoiceUser2x): VoiceUser2x = { + users += user.id -> user + user + } + + private def remove(id: String): Option[VoiceUser2x] = { + val user = users.get(id) + user foreach (u => users -= id) + user + } +} + +case class VoiceUser2x(id: String, voiceUserId: String) diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/models/VoiceUsersStatus.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/models/VoiceUsersStatus.scala new file mode 100755 index 0000000000000000000000000000000000000000..7b4a9893ca8ab6409c76267060439ffc43a66ae1 --- /dev/null +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/models/VoiceUsersStatus.scala @@ -0,0 +1,63 @@ +package org.bigbluebutton.core.models + +import com.softwaremill.quicklens._ + +object VoiceUsersStatus { + def findWithId(users: VoiceUsersStatus, userId: String): Option[VoiceStatus] = users.toVector.find(u => u.id == userId) + + def joinedVoiceListenOnly(users: VoiceUsersStatus, userId: String): Option[VoiceStatus] = { + for { + u <- findWithId(users, userId) + vu = u.modify(_.talking).setTo(false) + .modify(_.listenOnly).setTo(true) + } yield { + users.save(vu) + vu + } + } + + def leftVoiceListenOnly(users: VoiceUsersStatus, userId: String): Option[VoiceStatus] = { + for { + u <- findWithId(users, userId) + vu = u.modify(_.talking).setTo(false) + .modify(_.listenOnly).setTo(false) + } yield { + users.save(vu) + vu + } + } + + def setUserTalking(users: VoiceUsersStatus, user: VoiceStatus, talking: Boolean): VoiceStatus = { + val nv = user.modify(_.talking).setTo(talking) + users.save(nv) + nv + } + + def setUserMuted(users: VoiceUsersStatus, user: VoiceStatus, muted: Boolean): VoiceStatus = { + val talking: Boolean = if (muted) false else user.talking + val nv = user.modify(_.muted).setTo(muted).modify(_.talking).setTo(talking) + users.save(nv) + nv + } +} + +class VoiceUsersStatus { + private var users: collection.immutable.HashMap[String, VoiceStatus] = new collection.immutable.HashMap[String, VoiceStatus] + + private def toVector: Vector[VoiceStatus] = users.values.toVector + + private def save(user: VoiceStatus): VoiceStatus = { + users += user.id -> user + user + } + + private def remove(id: String): Option[VoiceStatus] = { + val user = users.get(id) + user foreach (u => users -= id) + user + } +} + +case class VoiceStatus(id: String, voiceUserId: String, callUsing: String, callerName: String, + callerNum: String, muted: Boolean, + talking: Boolean, listenOnly: Boolean) diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/models/Webcams.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/models/Webcams.scala index 4ae5197ee88caa1a62c1c370e16fc104b0236686..e1b2d9d50d79fbbb29b2293631bf8f9d2014055c 100755 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/models/Webcams.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/models/Webcams.scala @@ -1,5 +1,7 @@ package org.bigbluebutton.core.models +import org.bigbluebutton.core.models.Users.findWithId + object Webcams { def findWithStreamId(webcams: Webcams, streamId: String): Option[WebcamStream] = { webcams.toVector.find(w => w.stream.id == streamId) @@ -9,6 +11,38 @@ object Webcams { webcams.toVector.filter(w => w.userId == userId) } + def userSharedWebcam(userId: String, webcams: Webcams, streamId: String): Option[UserVO] = { + /* + for { + u <- findWithId(userId, users) + streams = u.webcamStreams + streamId + uvo = u.modify(_.hasStream).setTo(true).modify(_.webcamStreams).setTo(streams) + } yield { + users.save(uvo) + uvo + } + */ + None + } + + def userUnsharedWebcam(userId: String, webcams: Webcams, streamId: String): Option[UserVO] = { + /* + def findWebcamStream(streams: Set[String], stream: String): Option[String] = { + streams find (w => w == stream) + } + + for { + u <- findWebcamsForUser(webcams, userId) + streamName <- findWebcamStream(u.stream, streamId) + streams = u.webcamStreams - streamName + uvo = u.modify(_.hasStream).setTo(!streams.isEmpty).modify(_.webcamStreams).setTo(streams) + } yield { + users.save(uvo) + uvo + } + */ + None + } } class Webcams { diff --git a/akka-bbb-fsesl/src/main/java/org/bigbluebutton/freeswitch/pubsub/receivers/RedisMessageReceiver.java b/akka-bbb-fsesl/src/main/java/org/bigbluebutton/freeswitch/pubsub/receivers/RedisMessageReceiver.java new file mode 100755 index 0000000000000000000000000000000000000000..0e694e05f3279be7fe329c033568dc8376b7a1f5 --- /dev/null +++ b/akka-bbb-fsesl/src/main/java/org/bigbluebutton/freeswitch/pubsub/receivers/RedisMessageReceiver.java @@ -0,0 +1,139 @@ +package org.bigbluebutton.freeswitch.pubsub.receivers; + +import org.bigbluebutton.common.messages.EjectAllUsersFromVoiceConfRequestMessage; +import org.bigbluebutton.common.messages.EjectUserFromVoiceConfRequestMessage; +import org.bigbluebutton.common.messages.GetUsersFromVoiceConfRequestMessage; +import org.bigbluebutton.common.messages.MuteUserInVoiceConfRequestMessage; +import org.bigbluebutton.common.messages.StartRecordingVoiceConfRequestMessage; +import org.bigbluebutton.common.messages.StopRecordingVoiceConfRequestMessage; +import org.bigbluebutton.common.messages.TransferUserToVoiceConfRequestMessage; +import org.bigbluebutton.common.messages.DeskShareStartRTMPBroadcastEventMessage; +import org.bigbluebutton.common.messages.DeskShareStopRTMPBroadcastEventMessage; +import org.bigbluebutton.common.messages.DeskShareHangUpEventMessage; +import org.bigbluebutton.freeswitch.voice.freeswitch.FreeswitchApplication; + +import com.google.gson.JsonObject; +import com.google.gson.JsonParser; + +public class RedisMessageReceiver { + + public static final String TO_VOICE_CONF_CHANNEL = "bigbluebutton:to-voice-conf"; + public static final String TO_VOICE_CONF_PATTERN = TO_VOICE_CONF_CHANNEL + + ":*"; + public static final String TO_VOICE_CONF_SYSTEM_CHAN = TO_VOICE_CONF_CHANNEL + + ":system"; + + private final FreeswitchApplication fsApp; + + public RedisMessageReceiver(FreeswitchApplication fsApp) { + this.fsApp = fsApp; + } + + public void handleMessage(String pattern, String channel, String message) { + if (channel.equalsIgnoreCase(TO_VOICE_CONF_SYSTEM_CHAN)) { + JsonParser parser = new JsonParser(); + JsonObject obj = (JsonObject) parser.parse(message); + + if (obj.has("header") && obj.has("payload")) { + JsonObject header = (JsonObject) obj.get("header"); + + if (header.has("name")) { + String messageName = header.get("name").getAsString(); + switch (messageName) { + case EjectAllUsersFromVoiceConfRequestMessage.EJECT_ALL_VOICE_USERS_REQUEST: + processEjectAllVoiceUsersRequestMessage(message); + break; + case EjectUserFromVoiceConfRequestMessage.EJECT_VOICE_USER_REQUEST: + processEjectVoiceUserRequestMessage(message); + break; + case GetUsersFromVoiceConfRequestMessage.GET_VOICE_USERS_REQUEST: + processGetVoiceUsersRequestMessage(message); + break; + case MuteUserInVoiceConfRequestMessage.MUTE_VOICE_USER_REQUEST: + processMuteVoiceUserRequestMessage(message); + break; + case TransferUserToVoiceConfRequestMessage.TRANSFER_USER_TO_VOICE_CONF_REQUEST: + processTransferUserToVoiceConfRequestMessage(message); + break; + case StartRecordingVoiceConfRequestMessage.START_RECORD_VOICE_CONF_REQUEST: + processStartRecordingVoiceConfRequestMessage(message); + break; + case StopRecordingVoiceConfRequestMessage.STOP_RECORD_VOICE_CONF_REQUEST: + processStopRecordingVoiceConfRequestMessage(message); + break; + case DeskShareStartRTMPBroadcastEventMessage.DESKSHARE_START_RTMP_BROADCAST_MESSAGE: + System.out.println("RedisMessageReceiver got DESKSHARE_START_RTMP_BROADCAST_MESSAGE"); + processDeskShareStartRTMPBroadcastEventMessage(message); + break; + case DeskShareStopRTMPBroadcastEventMessage.DESKSHARE_STOP_RTMP_BROADCAST_MESSAGE: + System.out.println("RedisMessageReceiver got DESKSHARE_STOP_RTMP_BROADCAST_MESSAGE"); + processDeskShareStopRTMPBroadcastEventMessage(message); + break; + case DeskShareHangUpEventMessage.DESKSHARE_HANG_UP_MESSAGE: + System.out.println("RedisMessageReceiver got DESKSHARE_HANG_UP_MESSAGE"); + processDeskShareHangUpEventMessage(message); + break; + } + } + } + } + } + + private void processDeskShareStartRTMPBroadcastEventMessage(String json) { + DeskShareStartRTMPBroadcastEventMessage msg = DeskShareStartRTMPBroadcastEventMessage.fromJson(json); + fsApp.deskShareBroadcastRTMP(msg.conferenceName, msg.streamUrl, msg.timestamp, true); + } + + private void processDeskShareStopRTMPBroadcastEventMessage(String json) { + DeskShareStopRTMPBroadcastEventMessage msg = DeskShareStopRTMPBroadcastEventMessage.fromJson(json); + fsApp.deskShareBroadcastRTMP(msg.conferenceName, msg.streamUrl, msg.timestamp, false); + } + + private void processDeskShareHangUpEventMessage(String json) { + DeskShareHangUpEventMessage msg = DeskShareHangUpEventMessage.fromJson(json); + fsApp.deskShareHangUp(msg.conferenceName, msg.fsConferenceName, msg.timestamp); + } + + private void processEjectAllVoiceUsersRequestMessage(String json) { + EjectAllUsersFromVoiceConfRequestMessage msg = EjectAllUsersFromVoiceConfRequestMessage + .fromJson(json); + fsApp.ejectAll(msg.voiceConfId); + } + + private void processEjectVoiceUserRequestMessage(String json) { + EjectUserFromVoiceConfRequestMessage msg = EjectUserFromVoiceConfRequestMessage + .fromJson(json); + fsApp.eject(msg.voiceConfId, msg.voiceUserId); + } + + private void processGetVoiceUsersRequestMessage(String json) { + GetUsersFromVoiceConfRequestMessage msg = GetUsersFromVoiceConfRequestMessage + .fromJson(json); + fsApp.getAllUsers(msg.voiceConfId); + } + + private void processMuteVoiceUserRequestMessage(String json) { + MuteUserInVoiceConfRequestMessage msg = MuteUserInVoiceConfRequestMessage + .fromJson(json); + fsApp.muteUser(msg.voiceConfId, msg.voiceUserId, msg.mute); + } + + private void processTransferUserToVoiceConfRequestMessage(String json) { + TransferUserToVoiceConfRequestMessage msg = TransferUserToVoiceConfRequestMessage + .fromJson(json); + fsApp.transferUserToMeeting(msg.voiceConfId, msg.targetVoiceConfId, + msg.voiceUserId); + } + + private void processStartRecordingVoiceConfRequestMessage(String json) { + StartRecordingVoiceConfRequestMessage msg = StartRecordingVoiceConfRequestMessage + .fromJson(json); + fsApp.startRecording(msg.voiceConfId, msg.meetingId); + } + + private void processStopRecordingVoiceConfRequestMessage(String json) { + StopRecordingVoiceConfRequestMessage msg = StopRecordingVoiceConfRequestMessage + .fromJson(json); + fsApp.stopRecording(msg.voiceConfId, msg.meetingId, msg.recordStream); + } +} diff --git a/akka-bbb-fsesl/src/main/java/org/bigbluebutton/freeswitch/voice/ConferenceServerListener.java b/akka-bbb-fsesl/src/main/java/org/bigbluebutton/freeswitch/voice/ConferenceServerListener.java new file mode 100755 index 0000000000000000000000000000000000000000..ed86e5bf5a6b2a8bf4e7626d7ee1bde18b18cc8a --- /dev/null +++ b/akka-bbb-fsesl/src/main/java/org/bigbluebutton/freeswitch/voice/ConferenceServerListener.java @@ -0,0 +1,26 @@ +/** +* BigBlueButton open source conferencing system - http://www.bigbluebutton.org/ +* +* Copyright (c) 2012 BigBlueButton Inc. and by respective authors (see below). +* +* This program is free software; you can redistribute it and/or modify it under the +* terms of the GNU Lesser General Public License as published by the Free Software +* Foundation; either version 3.0 of the License, or (at your option) any later +* version. +* +* BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY +* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A +* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public License along +* with BigBlueButton; if not, see <http://www.gnu.org/licenses/>. +* +*/ +package org.bigbluebutton.freeswitch.voice; + +public interface ConferenceServerListener { + public void joined(String room, Integer participant, String name, Boolean muted, Boolean talking); + public void left(String room, Integer participant); + public void muted(String room, Integer participant, Boolean muted); + public void talking(String room, Integer participant, Boolean talking); +} diff --git a/akka-bbb-fsesl/src/main/java/org/bigbluebutton/freeswitch/voice/FreeswitchConferenceEventListener.java b/akka-bbb-fsesl/src/main/java/org/bigbluebutton/freeswitch/voice/FreeswitchConferenceEventListener.java new file mode 100755 index 0000000000000000000000000000000000000000..7fd3d8f6e29759226603a08641a07e33ceb7d1dc --- /dev/null +++ b/akka-bbb-fsesl/src/main/java/org/bigbluebutton/freeswitch/voice/FreeswitchConferenceEventListener.java @@ -0,0 +1,138 @@ +/** +* BigBlueButton open source conferencing system - http://www.bigbluebutton.org/ +* +* Copyright (c) 2012 BigBlueButton Inc. and by respective authors (see below). +* +* This program is free software; you can redistribute it and/or modify it under the +* terms of the GNU Lesser General Public License as published by the Free Software +* Foundation; either version 3.0 of the License, or (at your option) any later +* version. +* +* BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY +* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A +* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public License along +* with BigBlueButton; if not, see <http://www.gnu.org/licenses/>. +* +*/ +package org.bigbluebutton.freeswitch.voice; + +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.Executor; +import java.util.concurrent.Executors; +import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.TimeUnit; + +import org.bigbluebutton.freeswitch.voice.events.DeskShareStartedEvent; +import org.bigbluebutton.freeswitch.voice.events.DeskShareEndedEvent; +import org.bigbluebutton.freeswitch.voice.events.ConferenceEventListener; +import org.bigbluebutton.freeswitch.voice.events.DeskShareRTMPBroadcastEvent; +import org.bigbluebutton.freeswitch.voice.events.VoiceConferenceEvent; +import org.bigbluebutton.freeswitch.voice.events.VoiceStartRecordingEvent; +import org.bigbluebutton.freeswitch.voice.events.VoiceUserJoinedEvent; +import org.bigbluebutton.freeswitch.voice.events.VoiceUserLeftEvent; +import org.bigbluebutton.freeswitch.voice.events.VoiceUserMutedEvent; +import org.bigbluebutton.freeswitch.voice.events.VoiceUserTalkingEvent; + +public class FreeswitchConferenceEventListener implements ConferenceEventListener { + private static final int SENDERTHREADS = 1; + private static final Executor msgSenderExec = Executors.newFixedThreadPool(SENDERTHREADS); + private static final Executor runExec = Executors.newFixedThreadPool(SENDERTHREADS); + private BlockingQueue<VoiceConferenceEvent> messages = new LinkedBlockingQueue<VoiceConferenceEvent>(); + + private volatile boolean sendMessages = false; + private final IVoiceConferenceService vcs; + + public FreeswitchConferenceEventListener(IVoiceConferenceService vcs) { + this.vcs = vcs; + } + + private void queueMessage(VoiceConferenceEvent event) { + try { + messages.offer(event, 5, TimeUnit.SECONDS); + } catch (InterruptedException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + + private void sendMessageToBigBlueButton(final VoiceConferenceEvent event) { + Runnable task = new Runnable() { + public void run() { + if (event instanceof VoiceUserJoinedEvent) { + System.out.println("************** FreeswitchConferenceEventListener received voiceUserJoined "); + VoiceUserJoinedEvent evt = (VoiceUserJoinedEvent) event; + vcs.userJoinedVoiceConf(evt.getRoom(), evt.getVoiceUserId(), evt.getUserId(), evt.getCallerIdName(), + evt.getCallerIdNum(), evt.getMuted(), evt.getSpeaking(), evt.getAvatarURL()); + } else if (event instanceof VoiceUserLeftEvent) { + System.out.println("************** FreeswitchConferenceEventListener received VoiceUserLeftEvent "); + VoiceUserLeftEvent evt = (VoiceUserLeftEvent) event; + vcs.userLeftVoiceConf(evt.getRoom(), evt.getUserId()); + } else if (event instanceof VoiceUserMutedEvent) { + System.out.println("************** FreeswitchConferenceEventListener VoiceUserMutedEvent "); + VoiceUserMutedEvent evt = (VoiceUserMutedEvent) event; + vcs.userMutedInVoiceConf(evt.getRoom(), evt.getUserId(), evt.isMuted()); + } else if (event instanceof VoiceUserTalkingEvent) { + System.out.println("************** FreeswitchConferenceEventListener VoiceUserTalkingEvent "); + VoiceUserTalkingEvent evt = (VoiceUserTalkingEvent) event; + vcs.userTalkingInVoiceConf(evt.getRoom(), evt.getUserId(), evt.isTalking()); + } else if (event instanceof VoiceStartRecordingEvent) { + VoiceStartRecordingEvent evt = (VoiceStartRecordingEvent) event; + System.out.println("************** FreeswitchConferenceEventListener VoiceStartRecordingEvent recording=[" + evt.startRecord() + "]"); + vcs.voiceConfRecordingStarted(evt.getRoom(), evt.getRecordingFilename(), evt.startRecord(), evt.getTimestamp()); + } else if (event instanceof DeskShareStartedEvent) { + DeskShareStartedEvent evt = (DeskShareStartedEvent) event; + System.out.println("************** FreeswitchConferenceEventListener DeskShareStartedEvent"); + vcs.deskShareStarted(evt.getRoom(), evt.getCallerIdNum(), evt.getCallerIdName()); + } else if (event instanceof DeskShareEndedEvent) { + DeskShareEndedEvent evt = (DeskShareEndedEvent) event; + System.out.println("************** FreeswitchConferenceEventListener DeskShareEndedEvent"); + vcs.deskShareEnded(evt.getRoom(), evt.getCallerIdNum(), evt.getCallerIdName()); + } else if (event instanceof DeskShareRTMPBroadcastEvent) { + if (((DeskShareRTMPBroadcastEvent) event).getBroadcast()) { + DeskShareRTMPBroadcastEvent evt = (DeskShareRTMPBroadcastEvent) event; + System.out.println("************** FreeswitchConferenceEventListener DeskShareRTMPBroadcastStartedEvent"); + vcs.deskShareRTMPBroadcastStarted(evt.getRoom(), evt.getBroadcastingStreamUrl(), + evt.getVideoWidth(), evt.getVideoHeight(), evt.getTimestamp()); + } else { + DeskShareRTMPBroadcastEvent evt = (DeskShareRTMPBroadcastEvent) event; + System.out.println("************** FreeswitchConferenceEventListener DeskShareRTMPBroadcastStoppedEvent"); + vcs.deskShareRTMPBroadcastStopped(evt.getRoom(), evt.getBroadcastingStreamUrl(), + evt.getVideoWidth(), evt.getVideoHeight(), evt.getTimestamp()); + } + } + } + }; + + runExec.execute(task); + } + + public void start() { + sendMessages = true; + Runnable sender = new Runnable() { + public void run() { + while (sendMessages) { + VoiceConferenceEvent message; + try { + message = messages.take(); + sendMessageToBigBlueButton(message); + } catch (InterruptedException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + } + }; + msgSenderExec.execute(sender); + } + + public void stop() { + sendMessages = false; + } + + public void handleConferenceEvent(VoiceConferenceEvent event) { + queueMessage(event); + } + +} diff --git a/akka-bbb-fsesl/src/main/java/org/bigbluebutton/freeswitch/voice/IVoiceConferenceService.java b/akka-bbb-fsesl/src/main/java/org/bigbluebutton/freeswitch/voice/IVoiceConferenceService.java new file mode 100755 index 0000000000000000000000000000000000000000..0f0e2ab68736b2bfc8c1aac378db20b4eae602e6 --- /dev/null +++ b/akka-bbb-fsesl/src/main/java/org/bigbluebutton/freeswitch/voice/IVoiceConferenceService.java @@ -0,0 +1,16 @@ +package org.bigbluebutton.freeswitch.voice; + +public interface IVoiceConferenceService { + void voiceConfRecordingStarted(String voiceConfId, String recordStream, Boolean recording, String timestamp); + void userJoinedVoiceConf(String voiceConfId, String voiceUserId, String userId, String callerIdName, + String callerIdNum, Boolean muted, Boolean speaking, String avatarURL); + void userLeftVoiceConf(String voiceConfId, String voiceUserId); + void userLockedInVoiceConf(String voiceConfId, String voiceUserId, Boolean locked); + void userMutedInVoiceConf(String voiceConfId, String voiceUserId, Boolean muted); + void userTalkingInVoiceConf(String voiceConfId, String voiceUserId, Boolean talking); + void deskShareStarted(String voiceConfId, String callerIdNum, String callerIdName); + void deskShareEnded(String voiceConfId, String callerIdNum, String callerIdName); + void deskShareRTMPBroadcastStarted(String room, String streamname, Integer videoWidth, Integer videoHeight, String timestamp); + void deskShareRTMPBroadcastStopped(String room, String streamname, Integer videoWidth, Integer videoHeight, String timestamp); + +} diff --git a/akka-bbb-fsesl/src/main/java/org/bigbluebutton/freeswitch/voice/commands/ConferenceCommand.java b/akka-bbb-fsesl/src/main/java/org/bigbluebutton/freeswitch/voice/commands/ConferenceCommand.java new file mode 100755 index 0000000000000000000000000000000000000000..e4b93d716eaf74915ce68ac024927a69edb5ce7d --- /dev/null +++ b/akka-bbb-fsesl/src/main/java/org/bigbluebutton/freeswitch/voice/commands/ConferenceCommand.java @@ -0,0 +1,40 @@ +/** +* BigBlueButton open source conferencing system - http://www.bigbluebutton.org/ +* +* Copyright (c) 2012 BigBlueButton Inc. and by respective authors (see below). +* +* This program is free software; you can redistribute it and/or modify it under the +* terms of the GNU Lesser General Public License as published by the Free Software +* Foundation; either version 3.0 of the License, or (at your option) any later +* version. +* +* BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY +* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A +* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public License along +* with BigBlueButton; if not, see <http://www.gnu.org/licenses/>. +* +*/ +package org.bigbluebutton.freeswitch.voice.commands; + +public abstract class ConferenceCommand { + + private final String room; + private final Integer requesterId; + + public ConferenceCommand(String room, Integer requesterId) { + this.room = room; + this.requesterId = requesterId; + } + + public String getRoom() { + return room; + } + + public Integer getRequesterId() { + return requesterId; + } + + +} diff --git a/akka-bbb-fsesl/src/main/java/org/bigbluebutton/freeswitch/voice/commands/ConferenceCommandResult.java b/akka-bbb-fsesl/src/main/java/org/bigbluebutton/freeswitch/voice/commands/ConferenceCommandResult.java new file mode 100755 index 0000000000000000000000000000000000000000..ab7e12c09fcfaca4c8b3286f80b2012c2b48e57f --- /dev/null +++ b/akka-bbb-fsesl/src/main/java/org/bigbluebutton/freeswitch/voice/commands/ConferenceCommandResult.java @@ -0,0 +1,56 @@ +/** +* BigBlueButton open source conferencing system - http://www.bigbluebutton.org/ +* +* Copyright (c) 2012 BigBlueButton Inc. and by respective authors (see below). +* +* This program is free software; you can redistribute it and/or modify it under the +* terms of the GNU Lesser General Public License as published by the Free Software +* Foundation; either version 3.0 of the License, or (at your option) any later +* version. +* +* BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY +* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A +* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public License along +* with BigBlueButton; if not, see <http://www.gnu.org/licenses/>. +* +*/ +package org.bigbluebutton.freeswitch.voice.commands; + +public class ConferenceCommandResult { + + private final String room; + private final Integer requesterId; + private boolean success = false; + private String message = ""; + + public ConferenceCommandResult(String room, Integer requesterId) { + this.room = room; + this.requesterId = requesterId; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public String getRoom() { + return room; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public Integer getRequesterId() { + return requesterId; + } +} diff --git a/akka-bbb-fsesl/src/main/java/org/bigbluebutton/freeswitch/voice/commands/EjectUserCommand.java b/akka-bbb-fsesl/src/main/java/org/bigbluebutton/freeswitch/voice/commands/EjectUserCommand.java new file mode 100755 index 0000000000000000000000000000000000000000..3c29e2b63cb32816122c5163d242e0d2aa7dd946 --- /dev/null +++ b/akka-bbb-fsesl/src/main/java/org/bigbluebutton/freeswitch/voice/commands/EjectUserCommand.java @@ -0,0 +1,34 @@ +/** +* BigBlueButton open source conferencing system - http://www.bigbluebutton.org/ +* +* Copyright (c) 2012 BigBlueButton Inc. and by respective authors (see below). +* +* This program is free software; you can redistribute it and/or modify it under the +* terms of the GNU Lesser General Public License as published by the Free Software +* Foundation; either version 3.0 of the License, or (at your option) any later +* version. +* +* BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY +* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A +* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public License along +* with BigBlueButton; if not, see <http://www.gnu.org/licenses/>. +* +*/ +package org.bigbluebutton.freeswitch.voice.commands; + +public class EjectUserCommand extends ConferenceCommand { + + private final Integer participantId; + + public EjectUserCommand(String room, Integer requesterId, Integer participantId) { + super(room, requesterId); + this.participantId = participantId; + } + + public Integer getParticipantId() { + return participantId; + } + +} diff --git a/akka-bbb-fsesl/src/main/java/org/bigbluebutton/freeswitch/voice/commands/GetUsersCommand.java b/akka-bbb-fsesl/src/main/java/org/bigbluebutton/freeswitch/voice/commands/GetUsersCommand.java new file mode 100755 index 0000000000000000000000000000000000000000..13d21a4fb01e12c120779d3ad19f57e22900ce17 --- /dev/null +++ b/akka-bbb-fsesl/src/main/java/org/bigbluebutton/freeswitch/voice/commands/GetUsersCommand.java @@ -0,0 +1,27 @@ +/** +* BigBlueButton open source conferencing system - http://www.bigbluebutton.org/ +* +* Copyright (c) 2012 BigBlueButton Inc. and by respective authors (see below). +* +* This program is free software; you can redistribute it and/or modify it under the +* terms of the GNU Lesser General Public License as published by the Free Software +* Foundation; either version 3.0 of the License, or (at your option) any later +* version. +* +* BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY +* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A +* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public License along +* with BigBlueButton; if not, see <http://www.gnu.org/licenses/>. +* +*/ +package org.bigbluebutton.freeswitch.voice.commands; + +public class GetUsersCommand extends ConferenceCommand { + + public GetUsersCommand(String room, Integer requesterId) { + super(room, requesterId); + } + +} diff --git a/akka-bbb-fsesl/src/main/java/org/bigbluebutton/freeswitch/voice/commands/MuteUserCommand.java b/akka-bbb-fsesl/src/main/java/org/bigbluebutton/freeswitch/voice/commands/MuteUserCommand.java new file mode 100755 index 0000000000000000000000000000000000000000..62d2ece84c67079530da2fd55f74d9e0feb3435e --- /dev/null +++ b/akka-bbb-fsesl/src/main/java/org/bigbluebutton/freeswitch/voice/commands/MuteUserCommand.java @@ -0,0 +1,40 @@ +/** +* BigBlueButton open source conferencing system - http://www.bigbluebutton.org/ +* +* Copyright (c) 2012 BigBlueButton Inc. and by respective authors (see below). +* +* This program is free software; you can redistribute it and/or modify it under the +* terms of the GNU Lesser General Public License as published by the Free Software +* Foundation; either version 3.0 of the License, or (at your option) any later +* version. +* +* BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY +* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A +* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public License along +* with BigBlueButton; if not, see <http://www.gnu.org/licenses/>. +* +*/ +package org.bigbluebutton.freeswitch.voice.commands; + +public class MuteUserCommand extends ConferenceCommand { + + private final Integer participantId; + private final boolean mute; + + public MuteUserCommand(String room, Integer requesterId, Integer participantId, boolean mute) { + super(room, requesterId); + this.participantId = participantId; + this.mute = mute; + } + + public Integer getParticipantId() { + return participantId; + } + + public boolean isMute() { + return mute; + } + +} diff --git a/akka-bbb-fsesl/src/main/java/org/bigbluebutton/freeswitch/voice/commands/RecordCommand.java b/akka-bbb-fsesl/src/main/java/org/bigbluebutton/freeswitch/voice/commands/RecordCommand.java new file mode 100755 index 0000000000000000000000000000000000000000..bb60598dae0955413fc0f5a3172ec96e3420d960 --- /dev/null +++ b/akka-bbb-fsesl/src/main/java/org/bigbluebutton/freeswitch/voice/commands/RecordCommand.java @@ -0,0 +1,27 @@ +/** +* BigBlueButton open source conferencing system - http://www.bigbluebutton.org/ +* +* Copyright (c) 2012 BigBlueButton Inc. and by respective authors (see below). +* +* This program is free software; you can redistribute it and/or modify it under the +* terms of the GNU Lesser General Public License as published by the Free Software +* Foundation; either version 3.0 of the License, or (at your option) any later +* version. +* +* BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY +* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A +* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public License along +* with BigBlueButton; if not, see <http://www.gnu.org/licenses/>. +* +*/ +package org.bigbluebutton.freeswitch.voice.commands; + +public class RecordCommand extends ConferenceCommand { + + public RecordCommand(String room, Integer requesterId) { + super(room, requesterId); + } + +} diff --git a/akka-bbb-fsesl/src/main/java/org/bigbluebutton/freeswitch/voice/events/ConferenceEventListener.java b/akka-bbb-fsesl/src/main/java/org/bigbluebutton/freeswitch/voice/events/ConferenceEventListener.java new file mode 100755 index 0000000000000000000000000000000000000000..f277d8c4ebaf2a170336d1c489338d745a933abf --- /dev/null +++ b/akka-bbb-fsesl/src/main/java/org/bigbluebutton/freeswitch/voice/events/ConferenceEventListener.java @@ -0,0 +1,25 @@ +/** +* BigBlueButton open source conferencing system - http://www.bigbluebutton.org/ +* +* Copyright (c) 2012 BigBlueButton Inc. and by respective authors (see below). +* +* This program is free software; you can redistribute it and/or modify it under the +* terms of the GNU Lesser General Public License as published by the Free Software +* Foundation; either version 3.0 of the License, or (at your option) any later +* version. +* +* BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY +* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A +* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public License along +* with BigBlueButton; if not, see <http://www.gnu.org/licenses/>. +* +*/ +package org.bigbluebutton.freeswitch.voice.events; + + +public interface ConferenceEventListener { + public void handleConferenceEvent(VoiceConferenceEvent event); + +} diff --git a/akka-bbb-fsesl/src/main/java/org/bigbluebutton/freeswitch/voice/events/DeskShareEndedEvent.java b/akka-bbb-fsesl/src/main/java/org/bigbluebutton/freeswitch/voice/events/DeskShareEndedEvent.java new file mode 100644 index 0000000000000000000000000000000000000000..ea5e543e8e8709ca962ebf0d1a3b8951295b145e --- /dev/null +++ b/akka-bbb-fsesl/src/main/java/org/bigbluebutton/freeswitch/voice/events/DeskShareEndedEvent.java @@ -0,0 +1,39 @@ +/** +* BigBlueButton open source conferencing system - http://www.bigbluebutton.org/ +* +* Copyright (c) 2015 BigBlueButton Inc. and by respective authors (see below). +* +* This program is free software; you can redistribute it and/or modify it under the +* terms of the GNU Lesser General Public License as published by the Free Software +* Foundation; either version 3.0 of the License, or (at your option) any later +* version. +* +* BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY +* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A +* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public License along +* with BigBlueButton; if not, see <http://www.gnu.org/licenses/>. +* +*/ +package org.bigbluebutton.freeswitch.voice.events; + +public class DeskShareEndedEvent extends VoiceConferenceEvent { + + private final String callerIdNum; + private final String callerIdName; + + public DeskShareEndedEvent(String room, String callerIdNum, String callerIdName) { + super(room); + this.callerIdName = callerIdName; + this.callerIdNum = callerIdNum; + } + + public String getCallerIdNum() { + return callerIdNum; + } + + public String getCallerIdName() { + return callerIdName; + } +} diff --git a/akka-bbb-fsesl/src/main/java/org/bigbluebutton/freeswitch/voice/events/DeskShareRTMPBroadcastEvent.java b/akka-bbb-fsesl/src/main/java/org/bigbluebutton/freeswitch/voice/events/DeskShareRTMPBroadcastEvent.java new file mode 100644 index 0000000000000000000000000000000000000000..b939bc1dd371ffbbd02250bbb38ea08fb7737978 --- /dev/null +++ b/akka-bbb-fsesl/src/main/java/org/bigbluebutton/freeswitch/voice/events/DeskShareRTMPBroadcastEvent.java @@ -0,0 +1,68 @@ +/** +* BigBlueButton open source conferencing system - http://www.bigbluebutton.org/ +* +* Copyright (c) 2015 BigBlueButton Inc. and by respective authors (see below). +* +* This program is free software; you can redistribute it and/or modify it under the +* terms of the GNU Lesser General Public License as published by the Free Software +* Foundation; either version 3.0 of the License, or (at your option) any later +* version. +* +* BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY +* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A +* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public License along +* with BigBlueButton; if not, see <http://www.gnu.org/licenses/>. +* +*/ +package org.bigbluebutton.freeswitch.voice.events; + +public class DeskShareRTMPBroadcastEvent extends VoiceConferenceEvent { + + private String timestamp; + private boolean broadcast; + private String streamUrl; + private Integer vw; + private Integer vh; + + private final String DESKSHARE_SUFFIX = "-DESKSHARE"; + + + public DeskShareRTMPBroadcastEvent(String room, boolean broadcast) { + super(room); + this.broadcast = broadcast; + } + + public void setTimestamp(String timestamp) { + this.timestamp = timestamp; + } + + public void setBroadcastingStreamUrl(String streamUrl) { + this.streamUrl = streamUrl; + } + + public void setVideoWidth(Integer vw) {this.vw = vw;} + + public void setVideoHeight(Integer vh) {this.vh = vh;} + + public Integer getVideoHeight() {return vh;} + + public Integer getVideoWidth() {return vw;} + + public String getTimestamp() { + return timestamp; + } + + public String getBroadcastingStreamUrl() + { + if (streamUrl.endsWith(DESKSHARE_SUFFIX)) { + streamUrl = streamUrl.replace(DESKSHARE_SUFFIX, ""); + } + return streamUrl; + } + + public boolean getBroadcast() { + return broadcast; + } +} diff --git a/akka-bbb-fsesl/src/main/java/org/bigbluebutton/freeswitch/voice/events/DeskShareStartedEvent.java b/akka-bbb-fsesl/src/main/java/org/bigbluebutton/freeswitch/voice/events/DeskShareStartedEvent.java new file mode 100644 index 0000000000000000000000000000000000000000..9cb325ca8df14f2180482c0fc3e87a6e47af57a8 --- /dev/null +++ b/akka-bbb-fsesl/src/main/java/org/bigbluebutton/freeswitch/voice/events/DeskShareStartedEvent.java @@ -0,0 +1,39 @@ +/** +* BigBlueButton open source conferencing system - http://www.bigbluebutton.org/ +* +* Copyright (c) 2015 BigBlueButton Inc. and by respective authors (see below). +* +* This program is free software; you can redistribute it and/or modify it under the +* terms of the GNU Lesser General Public License as published by the Free Software +* Foundation; either version 3.0 of the License, or (at your option) any later +* version. +* +* BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY +* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A +* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public License along +* with BigBlueButton; if not, see <http://www.gnu.org/licenses/>. +* +*/ +package org.bigbluebutton.freeswitch.voice.events; + +public class DeskShareStartedEvent extends VoiceConferenceEvent { + + private final String callerIdNum; + private final String callerIdName; + + public DeskShareStartedEvent(String room, String callerIdNum, String callerIdName) { + super(room); + this.callerIdName = callerIdName; + this.callerIdNum = callerIdNum; + } + + public String getCallerIdNum() { + return callerIdNum; + } + + public String getCallerIdName() { + return callerIdName; + } +} diff --git a/akka-bbb-fsesl/src/main/java/org/bigbluebutton/freeswitch/voice/events/UnknownConferenceEvent.java b/akka-bbb-fsesl/src/main/java/org/bigbluebutton/freeswitch/voice/events/UnknownConferenceEvent.java new file mode 100755 index 0000000000000000000000000000000000000000..af959fad11130e01c6607a73e063fa47bbae84d7 --- /dev/null +++ b/akka-bbb-fsesl/src/main/java/org/bigbluebutton/freeswitch/voice/events/UnknownConferenceEvent.java @@ -0,0 +1,27 @@ +/** +* BigBlueButton open source conferencing system - http://www.bigbluebutton.org/ +* +* Copyright (c) 2012 BigBlueButton Inc. and by respective authors (see below). +* +* This program is free software; you can redistribute it and/or modify it under the +* terms of the GNU Lesser General Public License as published by the Free Software +* Foundation; either version 3.0 of the License, or (at your option) any later +* version. +* +* BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY +* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A +* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public License along +* with BigBlueButton; if not, see <http://www.gnu.org/licenses/>. +* +*/ +package org.bigbluebutton.freeswitch.voice.events; + +public class UnknownConferenceEvent extends VoiceConferenceEvent { + + public UnknownConferenceEvent(String participantId, String room) { + super(room); + } + +} diff --git a/akka-bbb-fsesl/src/main/java/org/bigbluebutton/freeswitch/voice/events/VoiceConferenceEvent.java b/akka-bbb-fsesl/src/main/java/org/bigbluebutton/freeswitch/voice/events/VoiceConferenceEvent.java new file mode 100755 index 0000000000000000000000000000000000000000..cf8bd96cfb9684b024eb5f8dd43459ef7fbeebb6 --- /dev/null +++ b/akka-bbb-fsesl/src/main/java/org/bigbluebutton/freeswitch/voice/events/VoiceConferenceEvent.java @@ -0,0 +1,32 @@ +/** +* BigBlueButton open source conferencing system - http://www.bigbluebutton.org/ +* +* Copyright (c) 2012 BigBlueButton Inc. and by respective authors (see below). +* +* This program is free software; you can redistribute it and/or modify it under the +* terms of the GNU Lesser General Public License as published by the Free Software +* Foundation; either version 3.0 of the License, or (at your option) any later +* version. +* +* BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY +* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A +* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public License along +* with BigBlueButton; if not, see <http://www.gnu.org/licenses/>. +* +*/ +package org.bigbluebutton.freeswitch.voice.events; + +public abstract class VoiceConferenceEvent { + private final String room; + + public VoiceConferenceEvent(String room) { + this.room = room; + } + + public String getRoom() { + return room; + } + +} diff --git a/akka-bbb-fsesl/src/main/java/org/bigbluebutton/freeswitch/voice/events/VoiceStartRecordingEvent.java b/akka-bbb-fsesl/src/main/java/org/bigbluebutton/freeswitch/voice/events/VoiceStartRecordingEvent.java new file mode 100755 index 0000000000000000000000000000000000000000..91bbc1dbab149f3fbeb12504d85c7e5db4cc7fbe --- /dev/null +++ b/akka-bbb-fsesl/src/main/java/org/bigbluebutton/freeswitch/voice/events/VoiceStartRecordingEvent.java @@ -0,0 +1,51 @@ +/** +* BigBlueButton open source conferencing system - http://www.bigbluebutton.org/ +* +* Copyright (c) 2012 BigBlueButton Inc. and by respective authors (see below). +* +* This program is free software; you can redistribute it and/or modify it under the +* terms of the GNU Lesser General Public License as published by the Free Software +* Foundation; either version 3.0 of the License, or (at your option) any later +* version. +* +* BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY +* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A +* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public License along +* with BigBlueButton; if not, see <http://www.gnu.org/licenses/>. +* +*/ +package org.bigbluebutton.freeswitch.voice.events; + +public class VoiceStartRecordingEvent extends VoiceConferenceEvent { + + private String timestamp; + private String filename; + private boolean record; + + public VoiceStartRecordingEvent(String room, boolean record) { + super(room); + this.record = record; + } + + public void setTimestamp(String timestamp) { + this.timestamp = timestamp; + } + + public void setRecordingFilename(String filename) { + this.filename = filename; + } + + public String getTimestamp() { + return timestamp; + } + + public String getRecordingFilename() { + return filename; + } + + public boolean startRecord() { + return record; + } +} diff --git a/akka-bbb-fsesl/src/main/java/org/bigbluebutton/freeswitch/voice/events/VoiceUserJoinedEvent.java b/akka-bbb-fsesl/src/main/java/org/bigbluebutton/freeswitch/voice/events/VoiceUserJoinedEvent.java new file mode 100755 index 0000000000000000000000000000000000000000..7ac8f398e7d277346d6d7c0f1e6b18b814c5723c --- /dev/null +++ b/akka-bbb-fsesl/src/main/java/org/bigbluebutton/freeswitch/voice/events/VoiceUserJoinedEvent.java @@ -0,0 +1,76 @@ +/** +* BigBlueButton open source conferencing system - http://www.bigbluebutton.org/ +* +* Copyright (c) 2012 BigBlueButton Inc. and by respective authors (see below). +* +* This program is free software; you can redistribute it and/or modify it under the +* terms of the GNU Lesser General Public License as published by the Free Software +* Foundation; either version 3.0 of the License, or (at your option) any later +* version. +* +* BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY +* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A +* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public License along +* with BigBlueButton; if not, see <http://www.gnu.org/licenses/>. +* +*/ +package org.bigbluebutton.freeswitch.voice.events; + +public class VoiceUserJoinedEvent extends VoiceConferenceEvent { + + private final String voiceUserId; + private final String callerIdNum; + private final String callerIdName; + private final Boolean muted; + private final Boolean speaking; + private final Boolean locked = false; + private final String userId; + private final String avatarURL; + + public VoiceUserJoinedEvent(String userId, String voiceUserId, String room, + String callerIdNum, String callerIdName, + Boolean muted, Boolean speaking, String avatarURL) { + super(room); + this.userId = userId; + this.voiceUserId = voiceUserId; + this.callerIdName = callerIdName; + this.callerIdNum = callerIdNum; + this.muted = muted; + this.speaking = speaking; + this.avatarURL = avatarURL; + } + + public String getUserId() { + return userId; + } + + public String getVoiceUserId() { + return voiceUserId; + } + + public String getCallerIdNum() { + return callerIdNum; + } + + public String getCallerIdName() { + return callerIdName; + } + + public Boolean getMuted() { + return muted; + } + + public Boolean getSpeaking() { + return speaking; + } + + public Boolean isLocked() { + return locked; + } + + public String getAvatarURL() { + return avatarURL; + } +} diff --git a/akka-bbb-fsesl/src/main/java/org/bigbluebutton/freeswitch/voice/events/VoiceUserLeftEvent.java b/akka-bbb-fsesl/src/main/java/org/bigbluebutton/freeswitch/voice/events/VoiceUserLeftEvent.java new file mode 100755 index 0000000000000000000000000000000000000000..7591db0153a99726e853eef0060a6aff3985be7a --- /dev/null +++ b/akka-bbb-fsesl/src/main/java/org/bigbluebutton/freeswitch/voice/events/VoiceUserLeftEvent.java @@ -0,0 +1,33 @@ +/** +* BigBlueButton open source conferencing system - http://www.bigbluebutton.org/ +* +* Copyright (c) 2012 BigBlueButton Inc. and by respective authors (see below). +* +* This program is free software; you can redistribute it and/or modify it under the +* terms of the GNU Lesser General Public License as published by the Free Software +* Foundation; either version 3.0 of the License, or (at your option) any later +* version. +* +* BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY +* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A +* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public License along +* with BigBlueButton; if not, see <http://www.gnu.org/licenses/>. +* +*/ +package org.bigbluebutton.freeswitch.voice.events; + +public class VoiceUserLeftEvent extends VoiceConferenceEvent { + + private final String userId; + + public VoiceUserLeftEvent(String userId, String room) { + super(room); + this.userId = userId; + } + + public String getUserId() { + return userId; + } +} diff --git a/akka-bbb-fsesl/src/main/java/org/bigbluebutton/freeswitch/voice/events/VoiceUserLockedEvent.java b/akka-bbb-fsesl/src/main/java/org/bigbluebutton/freeswitch/voice/events/VoiceUserLockedEvent.java new file mode 100755 index 0000000000000000000000000000000000000000..0cfc456dfedc2b5a68270b0511cf8f47b980fa2c --- /dev/null +++ b/akka-bbb-fsesl/src/main/java/org/bigbluebutton/freeswitch/voice/events/VoiceUserLockedEvent.java @@ -0,0 +1,40 @@ +/** +* BigBlueButton open source conferencing system - http://www.bigbluebutton.org/ +* +* Copyright (c) 2012 BigBlueButton Inc. and by respective authors (see below). +* +* This program is free software; you can redistribute it and/or modify it under the +* terms of the GNU Lesser General Public License as published by the Free Software +* Foundation; either version 3.0 of the License, or (at your option) any later +* version. +* +* BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY +* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A +* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public License along +* with BigBlueButton; if not, see <http://www.gnu.org/licenses/>. +* +*/ +package org.bigbluebutton.freeswitch.voice.events; + +public class VoiceUserLockedEvent extends VoiceConferenceEvent { + + private final boolean locked; + private final String userId; + + public VoiceUserLockedEvent(String userId, String room, boolean locked) { + super(room); + this.locked = locked; + this.userId = userId; + } + + public String getUserId() { + return userId; + } + + public boolean isLocked() { + return locked; + } + +} diff --git a/akka-bbb-fsesl/src/main/java/org/bigbluebutton/freeswitch/voice/events/VoiceUserMutedEvent.java b/akka-bbb-fsesl/src/main/java/org/bigbluebutton/freeswitch/voice/events/VoiceUserMutedEvent.java new file mode 100755 index 0000000000000000000000000000000000000000..003493b0f9c6020b82618d2a7228a915be71a5d6 --- /dev/null +++ b/akka-bbb-fsesl/src/main/java/org/bigbluebutton/freeswitch/voice/events/VoiceUserMutedEvent.java @@ -0,0 +1,40 @@ +/** +* BigBlueButton open source conferencing system - http://www.bigbluebutton.org/ +* +* Copyright (c) 2012 BigBlueButton Inc. and by respective authors (see below). +* +* This program is free software; you can redistribute it and/or modify it under the +* terms of the GNU Lesser General Public License as published by the Free Software +* Foundation; either version 3.0 of the License, or (at your option) any later +* version. +* +* BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY +* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A +* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public License along +* with BigBlueButton; if not, see <http://www.gnu.org/licenses/>. +* +*/ +package org.bigbluebutton.freeswitch.voice.events; + +public class VoiceUserMutedEvent extends VoiceConferenceEvent { + + private final boolean muted; + private final String userId; + + public VoiceUserMutedEvent(String userId, String room, boolean muted) { + super(room); + this.muted = muted; + this.userId = userId; + } + + public String getUserId() { + return userId; + } + + public boolean isMuted() { + return muted; + } + +} diff --git a/akka-bbb-fsesl/src/main/java/org/bigbluebutton/freeswitch/voice/events/VoiceUserTalkingEvent.java b/akka-bbb-fsesl/src/main/java/org/bigbluebutton/freeswitch/voice/events/VoiceUserTalkingEvent.java new file mode 100755 index 0000000000000000000000000000000000000000..5bd778062e7130472ee483e52046cf3342ea0657 --- /dev/null +++ b/akka-bbb-fsesl/src/main/java/org/bigbluebutton/freeswitch/voice/events/VoiceUserTalkingEvent.java @@ -0,0 +1,40 @@ +/** +* BigBlueButton open source conferencing system - http://www.bigbluebutton.org/ +* +* Copyright (c) 2012 BigBlueButton Inc. and by respective authors (see below). +* +* This program is free software; you can redistribute it and/or modify it under the +* terms of the GNU Lesser General Public License as published by the Free Software +* Foundation; either version 3.0 of the License, or (at your option) any later +* version. +* +* BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY +* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A +* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public License along +* with BigBlueButton; if not, see <http://www.gnu.org/licenses/>. +* +*/ +package org.bigbluebutton.freeswitch.voice.events; + +public class VoiceUserTalkingEvent extends VoiceConferenceEvent { + + private final boolean talking; + private final String userId; + + public VoiceUserTalkingEvent(String userId, String room, boolean talking) { + super(room); + this.talking = talking; + this.userId = userId; + } + + public String getUserId() { + return userId; + } + + public boolean isTalking() { + return talking; + } + +} diff --git a/akka-bbb-fsesl/src/main/java/org/bigbluebutton/freeswitch/voice/freeswitch/ConnectionManager.java b/akka-bbb-fsesl/src/main/java/org/bigbluebutton/freeswitch/voice/freeswitch/ConnectionManager.java new file mode 100755 index 0000000000000000000000000000000000000000..9e0ce5d5005cbe5a8fd45a39ba065c371cb4cd54 --- /dev/null +++ b/akka-bbb-fsesl/src/main/java/org/bigbluebutton/freeswitch/voice/freeswitch/ConnectionManager.java @@ -0,0 +1,178 @@ +/** + * BigBlueButton open source conferencing system - http://www.bigbluebutton.org/ + * + * Copyright (c) 2012 BigBlueButton Inc. and by respective authors (see below). + * + * This program is free software; you can redistribute it and/or modify it under the + * terms of the GNU Lesser General Public License as published by the Free Software + * Foundation; either version 3.0 of the License, or (at your option) any later + * version. + * + * BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A + * PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License along + * with BigBlueButton; if not, see <http://www.gnu.org/licenses/>. + * + */ +package org.bigbluebutton.freeswitch.voice.freeswitch; + +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.ScheduledFuture; +import java.util.concurrent.TimeUnit; +import org.bigbluebutton.freeswitch.voice.events.ConferenceEventListener; +import org.bigbluebutton.freeswitch.voice.freeswitch.actions.BroadcastConferenceCommand; +import org.bigbluebutton.freeswitch.voice.freeswitch.actions.EjectAllUsersCommand; +import org.bigbluebutton.freeswitch.voice.freeswitch.actions.EjectUserCommand; +import org.bigbluebutton.freeswitch.voice.freeswitch.actions.GetAllUsersCommand; +import org.bigbluebutton.freeswitch.voice.freeswitch.actions.MuteUserCommand; +import org.bigbluebutton.freeswitch.voice.freeswitch.actions.RecordConferenceCommand; +import org.bigbluebutton.freeswitch.voice.freeswitch.actions.TransferUserToMeetingCommand; +import org.bigbluebutton.freeswitch.voice.freeswitch.actions.*; +import org.freeswitch.esl.client.inbound.Client; +import org.freeswitch.esl.client.inbound.InboundConnectionFailure; +import org.freeswitch.esl.client.manager.ManagerConnection; +import org.freeswitch.esl.client.transport.message.EslMessage; + +public class ConnectionManager { + + private static final String EVENT_NAME = "Event-Name"; + + private static final ScheduledExecutorService connExec = Executors + .newSingleThreadScheduledExecutor(); + + private final ManagerConnection manager; + private ScheduledFuture<ConnectThread> connectTask; + + private volatile boolean subscribed = false; + + private final ConferenceEventListener conferenceEventListener; + private final ESLEventListener eslEventListener; + + public ConnectionManager(ManagerConnection connManager, + ESLEventListener eventListener, ConferenceEventListener confListener) { + this.manager = connManager; + this.eslEventListener = eventListener; + this.conferenceEventListener = confListener; + } + + private void connect() { + try { + Client c = manager.getESLClient(); + if (!c.canSend()) { + System.out.println("Attempting to connect to FreeSWITCH ESL"); + subscribed = false; + manager.connect(); + } else { + if (!subscribed) { + System.out.println("Subscribing for ESL events."); + c.cancelEventSubscriptions(); + c.addEventListener(eslEventListener); + c.setEventSubscriptions("plain", "all"); + c.addEventFilter(EVENT_NAME, "heartbeat"); + c.addEventFilter(EVENT_NAME, "custom"); + c.addEventFilter(EVENT_NAME, "background_job"); + subscribed = true; + } + } + } catch (InboundConnectionFailure e) { + System.out.println("Failed to connect to ESL"); + } + } + + public void start() { + System.out.println("Starting FreeSWITCH ESL connection manager."); + ConnectThread connector = new ConnectThread(); + connectTask = (ScheduledFuture<ConnectThread>) connExec + .scheduleAtFixedRate(connector, 5, 5, TimeUnit.SECONDS); + } + + public void stop() { + if (connectTask != null) { + connectTask.cancel(true); + } + } + + private class ConnectThread implements Runnable { + public void run() { + connect(); + } + } + + public void broadcast(BroadcastConferenceCommand rcc) { + Client c = manager.getESLClient(); + if (c.canSend()) { + EslMessage response = c.sendSyncApiCommand(rcc.getCommand(), + rcc.getCommandArgs()); + rcc.handleResponse(response, conferenceEventListener); + } + } + + public void getUsers(GetAllUsersCommand prc) { + Client c = manager.getESLClient(); + if (c.canSend()) { + EslMessage response = c.sendSyncApiCommand(prc.getCommand(), + prc.getCommandArgs()); + prc.handleResponse(response, conferenceEventListener); + } + } + + public void mute(MuteUserCommand mpc) { + System.out.println("Got mute request from FSApplication."); + Client c = manager.getESLClient(); + if (c.canSend()) { + System.out.println("Issuing command to FS ESL."); + c.sendAsyncApiCommand(mpc.getCommand(), mpc.getCommandArgs()); + } + } + + public void tranfer(TransferUserToMeetingCommand tutmc) { + Client c = manager.getESLClient(); + if (c.canSend()) { + c.sendAsyncApiCommand(tutmc.getCommand(), tutmc.getCommandArgs()); + } + } + + public void eject(EjectUserCommand mpc) { + Client c = manager.getESLClient(); + if (c.canSend()) { + c.sendAsyncApiCommand(mpc.getCommand(), mpc.getCommandArgs()); + } + } + + public void ejectAll(EjectAllUsersCommand mpc) { + Client c = manager.getESLClient(); + if (c.canSend()) { + c.sendAsyncApiCommand(mpc.getCommand(), mpc.getCommandArgs()); + } + } + + public void record(RecordConferenceCommand rcc) { + Client c = manager.getESLClient(); + if (c.canSend()) { + EslMessage response = c.sendSyncApiCommand(rcc.getCommand(), + rcc.getCommandArgs()); + rcc.handleResponse(response, conferenceEventListener); + } + } + + public void broadcastRTMP(DeskShareBroadcastRTMPCommand rtmp) { + Client c = manager.getESLClient(); + if (c.canSend()) { + System.out.println("ConnectionManager: send to FS: broadcastRTMP " + rtmp.getCommandArgs()); + EslMessage response = c.sendSyncApiCommand(rtmp.getCommand(), rtmp.getCommandArgs()); + rtmp.handleResponse(response, conferenceEventListener); + } + } + + public void hangUp(DeskShareHangUpCommand huCmd) { + Client c = manager.getESLClient(); + if (c.canSend()) { + System.out.println("ConnectionManager: send to FS: hangUp " + huCmd.getCommandArgs()); + EslMessage response = c.sendSyncApiCommand(huCmd.getCommand(), huCmd.getCommandArgs()); + huCmd.handleResponse(response, conferenceEventListener); + } + } +} diff --git a/akka-bbb-fsesl/src/main/java/org/bigbluebutton/freeswitch/voice/freeswitch/ESLEventListener.java b/akka-bbb-fsesl/src/main/java/org/bigbluebutton/freeswitch/voice/freeswitch/ESLEventListener.java new file mode 100755 index 0000000000000000000000000000000000000000..9e90a4a0f7e88a42cb0a3ecabe4d1e185450f2e5 --- /dev/null +++ b/akka-bbb-fsesl/src/main/java/org/bigbluebutton/freeswitch/voice/freeswitch/ESLEventListener.java @@ -0,0 +1,300 @@ +package org.bigbluebutton.freeswitch.voice.freeswitch; + + +import java.util.Map; +import java.util.concurrent.TimeUnit; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import org.bigbluebutton.freeswitch.voice.events.ConferenceEventListener; +import org.bigbluebutton.freeswitch.voice.events.DeskShareEndedEvent; +import org.bigbluebutton.freeswitch.voice.events.DeskShareStartedEvent; +import org.bigbluebutton.freeswitch.voice.events.DeskShareRTMPBroadcastEvent; +import org.bigbluebutton.freeswitch.voice.events.VoiceConferenceEvent; +import org.bigbluebutton.freeswitch.voice.events.VoiceStartRecordingEvent; +import org.bigbluebutton.freeswitch.voice.events.VoiceUserJoinedEvent; +import org.bigbluebutton.freeswitch.voice.events.VoiceUserLeftEvent; +import org.bigbluebutton.freeswitch.voice.events.VoiceUserMutedEvent; +import org.bigbluebutton.freeswitch.voice.events.VoiceUserTalkingEvent; +import org.freeswitch.esl.client.IEslEventListener; +import org.freeswitch.esl.client.transport.event.EslEvent; +import org.jboss.netty.channel.ExceptionEvent; + +public class ESLEventListener implements IEslEventListener { + + private static final String START_TALKING_EVENT = "start-talking"; + private static final String STOP_TALKING_EVENT = "stop-talking"; + private static final String START_RECORDING_EVENT = "start-recording"; + private static final String STOP_RECORDING_EVENT = "stop-recording"; + + private static final String DESKSHARE_CONFERENCE_NAME_SUFFIX = "-DESKSHARE"; + + private final ConferenceEventListener conferenceEventListener; + + public ESLEventListener(ConferenceEventListener conferenceEventListener) { + this.conferenceEventListener = conferenceEventListener; + } + + @Override + public void conferenceEventPlayFile(String uniqueId, String confName, int confSize, EslEvent event) { + //Ignored, Noop + } + + @Override + public void backgroundJobResultReceived(EslEvent event) { + System.out.println( "Background job result received [" + event + "]"); + } + + @Override + public void exceptionCaught(ExceptionEvent e) { +// setChanged(); +// notifyObservers(e); + } + + private static final Pattern GLOBAL_AUDION_PATTERN = Pattern.compile("(GLOBAL_AUDIO)_(.*)$"); + private static final Pattern CALLERNAME_PATTERN = Pattern.compile("(.*)-bbbID-(.*)$"); + + @Override + public void conferenceEventJoin(String uniqueId, String confName, int confSize, EslEvent event) { + + Integer memberId = this.getMemberIdFromEvent(event); + Map<String, String> headers = event.getEventHeaders(); + String callerId = this.getCallerIdFromEvent(event); + String callerIdName = this.getCallerIdNameFromEvent(event); + boolean muted = headers.get("Speak").equals("true") ? false : true; //Was inverted which was causing a State issue + boolean speaking = headers.get("Talking").equals("true") ? true : false; + + String voiceUserId = callerIdName; + + Matcher gapMatcher = GLOBAL_AUDION_PATTERN.matcher(callerIdName); + if (gapMatcher.matches()) { + System.out.println("Ignoring GLOBAL AUDIO USER [" + callerIdName + "]"); + return; + } + + // (WebRTC) Deskstop sharing conferences' name is of the form ddddd-DESKSHARE + // Voice conferences' name is of the form ddddd + if (confName.endsWith(DESKSHARE_CONFERENCE_NAME_SUFFIX)) { + System.out.println("User joined deskshare conference, user=[" + callerIdName + "], " + + "conf=[" + confName + "] callerId=[" + callerId + "]"); + DeskShareStartedEvent dsStart = new DeskShareStartedEvent(confName, callerId, callerIdName); + conferenceEventListener.handleConferenceEvent(dsStart); + } else { + Matcher matcher = CALLERNAME_PATTERN.matcher(callerIdName); + if (matcher.matches()) { + voiceUserId = matcher.group(1).trim(); + callerIdName = matcher.group(2).trim(); + } + + System.out.println("User joined voice conference, user=[" + callerIdName + "], conf=[" + + confName + "] callerId=[" + callerId + "]"); + + VoiceUserJoinedEvent pj = new VoiceUserJoinedEvent(voiceUserId, memberId.toString(), confName, callerId, callerIdName, muted, speaking, "none"); + conferenceEventListener.handleConferenceEvent(pj); + } + } + + @Override + public void conferenceEventLeave(String uniqueId, String confName, int confSize, EslEvent event) { + Integer memberId = this.getMemberIdFromEvent(event); + String callerId = this.getCallerIdFromEvent(event); + String callerIdName = this.getCallerIdNameFromEvent(event); + + // (WebRTC) Deskstop sharing conferences' name is of the form ddddd-DESKSHARE + // Voice conferences' name is of the form ddddd + if (confName.endsWith(DESKSHARE_CONFERENCE_NAME_SUFFIX)) { + System.out.println("User left deskshare conference, user=[" + memberId.toString() + + "], " + "conf=[" + confName + "]"); + DeskShareEndedEvent dsEnd = new DeskShareEndedEvent(confName, callerId, callerIdName); + conferenceEventListener.handleConferenceEvent(dsEnd); + } else { + System.out.println("User left voice conference, user=[" + memberId.toString() + "], " + + "conf=[" + confName + "]"); + VoiceUserLeftEvent pl = new VoiceUserLeftEvent(memberId.toString(), confName); + conferenceEventListener.handleConferenceEvent(pl); + } + } + + @Override + public void conferenceEventMute(String uniqueId, String confName, int confSize, EslEvent event) { + Integer memberId = this.getMemberIdFromEvent(event); + System.out.println("******************** Received Conference Muted Event from FreeSWITCH user[" + memberId.toString() + "]"); + System.out.println("User muted voice conference, user=[" + memberId.toString() + "], conf=[" + confName + "]"); + VoiceUserMutedEvent pm = new VoiceUserMutedEvent(memberId.toString(), confName, true); + conferenceEventListener.handleConferenceEvent(pm); + } + + @Override + public void conferenceEventUnMute(String uniqueId, String confName, int confSize, EslEvent event) { + Integer memberId = this.getMemberIdFromEvent(event); + System.out.println("******************** Received ConferenceUnmuted Event from FreeSWITCH user[" + memberId.toString() + "]"); + System.out.println("User unmuted voice conference, user=[" + memberId.toString() + "], conf=[" + confName + "]"); + VoiceUserMutedEvent pm = new VoiceUserMutedEvent(memberId.toString(), confName, false); + conferenceEventListener.handleConferenceEvent(pm); + } + + @Override + public void conferenceEventAction(String uniqueId, String confName, int confSize, String action, EslEvent event) { + Integer memberId = this.getMemberIdFromEvent(event); + VoiceUserTalkingEvent pt; + + System.out.println("******************** Receive conference Action [" + action + "]"); + + if (action == null) { + return; + } + + if (action.equals(START_TALKING_EVENT)) { + pt = new VoiceUserTalkingEvent(memberId.toString(), confName, true); + conferenceEventListener.handleConferenceEvent(pt); + } else if (action.equals(STOP_TALKING_EVENT)) { + pt = new VoiceUserTalkingEvent(memberId.toString(), confName, false); + conferenceEventListener.handleConferenceEvent(pt); + } else { + System.out.println("Unknown conference Action [" + action + "]"); + } + } + + @Override + public void conferenceEventTransfer(String uniqueId, String confName, int confSize, EslEvent event) { + //Ignored, Noop + } + + @Override + public void conferenceEventThreadRun(String uniqueId, String confName, int confSize, EslEvent event) { + + } + + //@Override + public void conferenceEventRecord(String uniqueId, String confName, int confSize, EslEvent event) { + String action = event.getEventHeaders().get("Action"); + + if(action == null) { + return; + } + + if (action.equals(START_RECORDING_EVENT)) { + if (confName.endsWith(DESKSHARE_CONFERENCE_NAME_SUFFIX)){ + if (isRTMPStream(event)) { + DeskShareRTMPBroadcastEvent rtmp = new DeskShareRTMPBroadcastEvent(confName, true); + rtmp.setBroadcastingStreamUrl(getStreamUrl(event)); + rtmp.setVideoHeight(Integer.parseInt(getBroadcastParameter(event, "vh"))); + rtmp.setVideoWidth(Integer.parseInt(getBroadcastParameter(event, "vw"))); + rtmp.setTimestamp(genTimestamp().toString()); + + System.out.println("DeskShare conference broadcast started. url=[" + + getStreamUrl(event) + "], conf=[" + confName + "]"); + conferenceEventListener.handleConferenceEvent(rtmp); + } + } else { + VoiceStartRecordingEvent sre = new VoiceStartRecordingEvent(confName, true); + sre.setRecordingFilename(getRecordFilenameFromEvent(event)); + sre.setTimestamp(genTimestamp().toString()); + + System.out.println("Voice conference recording started. file=[" + + getRecordFilenameFromEvent(event) + "], conf=[" + confName + "]"); + conferenceEventListener.handleConferenceEvent(sre); + } + } else if (action.equals(STOP_RECORDING_EVENT)) { + if (confName.endsWith(DESKSHARE_CONFERENCE_NAME_SUFFIX)){ + if (isRTMPStream(event)) { + DeskShareRTMPBroadcastEvent rtmp = new DeskShareRTMPBroadcastEvent(confName, false); + rtmp.setBroadcastingStreamUrl(getStreamUrl(event)); + rtmp.setVideoHeight(Integer.parseInt(getBroadcastParameter(event, "vh"))); + rtmp.setVideoWidth(Integer.parseInt(getBroadcastParameter(event, "vw"))); + rtmp.setTimestamp(genTimestamp().toString()); + + System.out.println("DeskShare conference broadcast stopped. url=[" + + getStreamUrl(event) + "], conf=[" + confName + "]"); + conferenceEventListener.handleConferenceEvent(rtmp); + } + } else { + VoiceStartRecordingEvent sre = new VoiceStartRecordingEvent(confName, false); + sre.setRecordingFilename(getRecordFilenameFromEvent(event)); + sre.setTimestamp(genTimestamp().toString()); + System.out.println("Voice conference recording stopped. file=[" + + getRecordFilenameFromEvent(event) + "], conf=[" + confName + "]"); + conferenceEventListener.handleConferenceEvent(sre); + } + } + + else { + System.out.println("Processing UNKNOWN conference Action " + action + "]"); + } + } + + private Long genTimestamp() { + return TimeUnit.NANOSECONDS.toMillis(System.nanoTime()); + } + + @Override + public void eventReceived(EslEvent event) { + System.out.println("ESL Event Listener received event=[" + event.getEventName() + "]" + + event.getEventHeaders().toString()); +// if (event.getEventName().equals(FreeswitchHeartbeatMonitor.EVENT_HEARTBEAT)) { +//// setChanged(); +// notifyObservers(event); +// return; +// } + } + + private Integer getMemberIdFromEvent(EslEvent e) { + return new Integer(e.getEventHeaders().get("Member-ID")); + } + + private String getCallerIdFromEvent(EslEvent e) { + return e.getEventHeaders().get("Caller-Caller-ID-Number"); + } + + private String getCallerIdNameFromEvent(EslEvent e) { + return e.getEventHeaders().get("Caller-Caller-ID-Name"); + } + + private String getRecordFilenameFromEvent(EslEvent e) { + return e.getEventHeaders().get("Path"); + } + + // Distinguish between recording to a file: + // /path/to/a/file.mp4 + // and broadcasting a stream: + // {channels=2,samplerate=48000,vw=1920,vh=1080,fps=15.00}rtmp://192.168.0.109/live/abc/dev-test + private Boolean isRTMPStream(EslEvent e) { + String path = e.getEventHeaders().get("Path"); + + if (path.contains("rtmp") && path.contains("channels") + && path.contains("samplerate") && path.contains("vw") + && path.contains("vh") && path.contains("fps")) { + return true; + } else { + return false; + } + } + + // returns a String so that we can parse to an int or double depending on the param + private String getBroadcastParameter(EslEvent e, String param) { + String path = e.getEventHeaders().get("Path"); + if (isRTMPStream(e)) { + String temp = path.substring(path.indexOf("{") + 1, path.indexOf("}")); + String[] arr = temp.split(","); + for (int i = 0; i < 5; i++) { + if (arr[i].startsWith(param)) { + return arr[i].substring(arr[i].indexOf('=') + 1); + } + } + return "0"; + } else { + return "0"; + } + } + + // Obtain the rtmp url from the event (if any): + private String getStreamUrl(EslEvent e) { + String path = e.getEventHeaders().get("Path"); + if (isRTMPStream(e)){ + return path.substring(path.lastIndexOf("}") + 1); + } else { + return ""; + } + } + +} diff --git a/akka-bbb-fsesl/src/main/java/org/bigbluebutton/freeswitch/voice/freeswitch/FreeswitchApplication.java b/akka-bbb-fsesl/src/main/java/org/bigbluebutton/freeswitch/voice/freeswitch/FreeswitchApplication.java new file mode 100755 index 0000000000000000000000000000000000000000..d39365f7cd45b1add48bfea8b89bdc2541dff421 --- /dev/null +++ b/akka-bbb-fsesl/src/main/java/org/bigbluebutton/freeswitch/voice/freeswitch/FreeswitchApplication.java @@ -0,0 +1,183 @@ +/** + * BigBlueButton open source conferencing system - http://www.bigbluebutton.org/ + * <p> + * Copyright (c) 2015 BigBlueButton Inc. and by respective authors (see below). + * <p> + * This program is free software; you can redistribute it and/or modify it under the + * terms of the GNU Lesser General Public License as published by the Free Software + * Foundation; either version 3.0 of the License, or (at your option) any later + * version. + * <p> + * BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A + * PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. + * <p> + * You should have received a copy of the GNU Lesser General Public License along + * with BigBlueButton; if not, see <http://www.gnu.org/licenses/>. + */ +package org.bigbluebutton.freeswitch.voice.freeswitch; + +import java.io.File; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.Executor; +import java.util.concurrent.Executors; +import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.TimeUnit; + +import org.bigbluebutton.freeswitch.voice.freeswitch.actions.BroadcastConferenceCommand; +import org.bigbluebutton.freeswitch.voice.freeswitch.actions.EjectAllUsersCommand; +import org.bigbluebutton.freeswitch.voice.freeswitch.actions.EjectUserCommand; +import org.bigbluebutton.freeswitch.voice.freeswitch.actions.FreeswitchCommand; +import org.bigbluebutton.freeswitch.voice.freeswitch.actions.GetAllUsersCommand; +import org.bigbluebutton.freeswitch.voice.freeswitch.actions.MuteUserCommand; +import org.bigbluebutton.freeswitch.voice.freeswitch.actions.RecordConferenceCommand; +import org.bigbluebutton.freeswitch.voice.freeswitch.actions.TransferUserToMeetingCommand; +import org.bigbluebutton.freeswitch.voice.freeswitch.actions.*; + +public class FreeswitchApplication { + + private static final int SENDERTHREADS = 1; + private static final Executor msgSenderExec = Executors.newFixedThreadPool(SENDERTHREADS); + private static final Executor runExec = Executors.newFixedThreadPool(SENDERTHREADS); + private BlockingQueue<FreeswitchCommand> messages = new LinkedBlockingQueue<FreeswitchCommand>(); + + private final ConnectionManager manager; + + private final String USER = "0"; /* not used for now */ + + private volatile boolean sendMessages = false; + + private final String audioProfile; + + public FreeswitchApplication(ConnectionManager manager, String profile) { + this.manager = manager; + this.audioProfile = profile; + } + + private void queueMessage(FreeswitchCommand command) { + try { + messages.offer(command, 5, TimeUnit.SECONDS); + } catch (InterruptedException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + + public void transferUserToMeeting(String voiceConfId, + String targetVoiceConfId, String voiceUserId) { + TransferUserToMeetingCommand tutmc = new TransferUserToMeetingCommand( + voiceConfId, targetVoiceConfId, voiceUserId, this.audioProfile, + USER); + queueMessage(tutmc); + } + + public void start() { + sendMessages = true; + Runnable sender = new Runnable() { + public void run() { + while (sendMessages) { + FreeswitchCommand message; + try { + message = messages.take(); + sendMessageToFreeswitch(message); + } catch (InterruptedException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + } + }; + msgSenderExec.execute(sender); + } + + public void getAllUsers(String voiceConfId) { + GetAllUsersCommand prc = new GetAllUsersCommand(voiceConfId, USER); + queueMessage(prc); + } + + public void muteUser(String voiceConfId, String voiceUserId, Boolean mute) { + MuteUserCommand mpc = new MuteUserCommand(voiceConfId, voiceUserId, mute, USER); + queueMessage(mpc); + } + + public void eject(String voiceConfId, String voiceUserId) { + EjectUserCommand mpc = new EjectUserCommand(voiceConfId, voiceUserId, USER); + queueMessage(mpc); + } + + public void ejectAll(String voiceConfId) { + EjectAllUsersCommand mpc = new EjectAllUsersCommand(voiceConfId, USER); + queueMessage(mpc); + } + + private Long genTimestamp() { + return TimeUnit.NANOSECONDS.toMillis(System.nanoTime()); + } + + public void startRecording(String voiceConfId, String meetingid) { + String RECORD_DIR = "/var/freeswitch/meetings"; + String voicePath = RECORD_DIR + File.separatorChar + meetingid + "-" + genTimestamp() + ".wav"; + + RecordConferenceCommand rcc = new RecordConferenceCommand(voiceConfId, USER, true, voicePath); + queueMessage(rcc); + } + + public void stopRecording(String voiceConfId, String meetingid, String voicePath) { + RecordConferenceCommand rcc = new RecordConferenceCommand(voiceConfId, USER, false, voicePath); + queueMessage(rcc); + } + + public void deskShareBroadcastRTMP(String voiceConfId, String streamUrl, String timestamp, Boolean broadcast) { + DeskShareBroadcastRTMPCommand rtmp = new DeskShareBroadcastRTMPCommand(voiceConfId, USER, streamUrl, timestamp, broadcast); + queueMessage(rtmp); + } + + public void deskShareHangUp(String voiceConfId, String fsConferenceName, String timestamp) { + DeskShareHangUpCommand huCmd = new DeskShareHangUpCommand(voiceConfId, fsConferenceName, USER, timestamp); + queueMessage(huCmd); + } + + private void sendMessageToFreeswitch(final FreeswitchCommand command) { + Runnable task = new Runnable() { + public void run() { + if (command instanceof GetAllUsersCommand) { + GetAllUsersCommand cmd = (GetAllUsersCommand) command; + System.out.println("Sending PopulateRoomCommand for conference = [" + cmd.getRoom() + "]"); + manager.getUsers(cmd); + } else if (command instanceof MuteUserCommand) { + MuteUserCommand cmd = (MuteUserCommand) command; + System.out.println("Sending MuteParticipantCommand for conference = [" + cmd.getRoom() + "]"); + manager.mute(cmd); + } else if (command instanceof EjectUserCommand) { + EjectUserCommand cmd = (EjectUserCommand) command; + System.out.println("Sending EjectParticipantCommand for conference = [" + cmd.getRoom() + "]"); + manager.eject(cmd); + } else if (command instanceof EjectAllUsersCommand) { + EjectAllUsersCommand cmd = (EjectAllUsersCommand) command; + System.out.println("Sending EjectAllUsersCommand for conference = [" + cmd.getRoom() + "]"); + manager.ejectAll(cmd); + } else if (command instanceof TransferUserToMeetingCommand) { + TransferUserToMeetingCommand cmd = (TransferUserToMeetingCommand) command; + System.out.println("Sending TransferUsetToMeetingCommand for conference = [" + + cmd.getRoom() + "]"); + manager.tranfer(cmd); + } else if (command instanceof RecordConferenceCommand) { + manager.record((RecordConferenceCommand) command); + } else if (command instanceof DeskShareBroadcastRTMPCommand) { + manager.broadcastRTMP((DeskShareBroadcastRTMPCommand) command); + } else if (command instanceof DeskShareHangUpCommand) { + DeskShareHangUpCommand cmd = (DeskShareHangUpCommand) command; + manager.hangUp(cmd); + } else if (command instanceof BroadcastConferenceCommand) { + manager.broadcast((BroadcastConferenceCommand) command); + } + } + }; + + runExec.execute(task); + } + + public void stop() { + sendMessages = false; + } +} diff --git a/akka-bbb-fsesl/src/main/java/org/bigbluebutton/freeswitch/voice/freeswitch/actions/BroadcastConferenceCommand.java b/akka-bbb-fsesl/src/main/java/org/bigbluebutton/freeswitch/voice/freeswitch/actions/BroadcastConferenceCommand.java new file mode 100755 index 0000000000000000000000000000000000000000..45ef88764f558f057c764ee0d59f5b3911018d20 --- /dev/null +++ b/akka-bbb-fsesl/src/main/java/org/bigbluebutton/freeswitch/voice/freeswitch/actions/BroadcastConferenceCommand.java @@ -0,0 +1,50 @@ +/** +* BigBlueButton open source conferencing system - http://www.bigbluebutton.org/ +* +* Copyright (c) 2012 BigBlueButton Inc. and by respective authors (see below). +* +* This program is free software; you can redistribute it and/or modify it under the +* terms of the GNU Lesser General Public License as published by the Free Software +* Foundation; either version 3.0 of the License, or (at your option) any later +* version. +* +* BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY +* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A +* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public License along +* with BigBlueButton; if not, see <http://www.gnu.org/licenses/>. +* +*/ +package org.bigbluebutton.freeswitch.voice.freeswitch.actions; + +import org.bigbluebutton.freeswitch.voice.events.ConferenceEventListener; +import org.freeswitch.esl.client.transport.message.EslMessage; + +public class BroadcastConferenceCommand extends FreeswitchCommand { + private boolean record; + private String icecastPath; + + public BroadcastConferenceCommand(String room, String requesterId, boolean record, String icecastPath){ + super(room, requesterId); + this.record = record; + this.icecastPath = icecastPath; + } + + + @Override + public String getCommandArgs() { + String action = "norecord"; + if (record) + action = "record"; + + return SPACE + getRoom() + SPACE + action + SPACE + icecastPath; + } + + public void handleResponse(EslMessage response, ConferenceEventListener eventListener) { + + //Test for Known Conference + + + } +} diff --git a/akka-bbb-fsesl/src/main/java/org/bigbluebutton/freeswitch/voice/freeswitch/actions/DeskShareBroadcastRTMPCommand.java b/akka-bbb-fsesl/src/main/java/org/bigbluebutton/freeswitch/voice/freeswitch/actions/DeskShareBroadcastRTMPCommand.java new file mode 100644 index 0000000000000000000000000000000000000000..67cd5130aa9696fc478d773f49349c0ff0049460 --- /dev/null +++ b/akka-bbb-fsesl/src/main/java/org/bigbluebutton/freeswitch/voice/freeswitch/actions/DeskShareBroadcastRTMPCommand.java @@ -0,0 +1,58 @@ +/** +* BigBlueButton open source conferencing system - http://www.bigbluebutton.org/ +* +* Copyright (c) 2015 BigBlueButton Inc. and by respective authors (see below). +* +* This program is free software; you can redistribute it and/or modify it under the +* terms of the GNU Lesser General Public License as published by the Free Software +* Foundation; either version 3.0 of the License, or (at your option) any later +* version. +* +* BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY +* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A +* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public License along +* with BigBlueButton; if not, see <http://www.gnu.org/licenses/>. +* +*/ +package org.bigbluebutton.freeswitch.voice.freeswitch.actions; + +import org.bigbluebutton.freeswitch.voice.events.ConferenceEventListener; +import org.freeswitch.esl.client.transport.message.EslMessage; + +public class DeskShareBroadcastRTMPCommand extends FreeswitchCommand { + + private String broadcastPath; + private boolean broadcast; + private String timestamp; + private final String DESKSHARE_SUFFIX = "-DESKSHARE"; + + public DeskShareBroadcastRTMPCommand(String room, String requesterId, String broadcastPath, String timestamp, boolean broadcast){ + super(room, requesterId); + this.broadcastPath = broadcastPath; + this.broadcast = broadcast; + this.timestamp = timestamp; + } + + + @Override + public String getCommandArgs() { + String action = "norecord"; + if (broadcast) { + action = "record"; + } + + String room = getRoom(); + if (!room.endsWith(DESKSHARE_SUFFIX)) { + room = room + DESKSHARE_SUFFIX; + } + + return SPACE + room + SPACE + action + SPACE + broadcastPath; + } + + public void handleResponse(EslMessage response, ConferenceEventListener eventListener) { + //Test for Known Conference + System.out.println("\nDeskShareBroadcastRTMPCommand\n"); + } +} diff --git a/akka-bbb-fsesl/src/main/java/org/bigbluebutton/freeswitch/voice/freeswitch/actions/DeskShareHangUpCommand.java b/akka-bbb-fsesl/src/main/java/org/bigbluebutton/freeswitch/voice/freeswitch/actions/DeskShareHangUpCommand.java new file mode 100644 index 0000000000000000000000000000000000000000..7c2e5537bdf5ad516ca9f1a197a594a33a5b5810 --- /dev/null +++ b/akka-bbb-fsesl/src/main/java/org/bigbluebutton/freeswitch/voice/freeswitch/actions/DeskShareHangUpCommand.java @@ -0,0 +1,35 @@ +package org.bigbluebutton.freeswitch.voice.freeswitch.actions; + +import org.bigbluebutton.freeswitch.voice.events.ConferenceEventListener; +import org.freeswitch.esl.client.transport.message.EslMessage; + +/** + * Created by anton on 07/01/16. + */ +public class DeskShareHangUpCommand extends FreeswitchCommand { + private String timestamp; + private String fsConferenceName; + private final String DESKSHARE_SUFFIX = "-DESKSHARE"; + + public DeskShareHangUpCommand(String room, String fsConferenceName, String requesterId, String timestamp){ + super(room, requesterId); + this.timestamp = timestamp; + this.fsConferenceName = fsConferenceName; + } + + + @Override + public String getCommandArgs() { + String action = "kick all"; + + if(!fsConferenceName.endsWith(DESKSHARE_SUFFIX)) { + fsConferenceName = fsConferenceName + DESKSHARE_SUFFIX; + } + return SPACE + fsConferenceName + SPACE + action; + } + + public void handleResponse(EslMessage response, ConferenceEventListener eventListener) { + System.out.println("\nDeskShareHangUpCommand\n"); + } +} + diff --git a/akka-bbb-fsesl/src/main/java/org/bigbluebutton/freeswitch/voice/freeswitch/actions/DeskShareRecordCommand.java b/akka-bbb-fsesl/src/main/java/org/bigbluebutton/freeswitch/voice/freeswitch/actions/DeskShareRecordCommand.java new file mode 100644 index 0000000000000000000000000000000000000000..ff5e733558b8b8ba62375795f750ed6112cbbb42 --- /dev/null +++ b/akka-bbb-fsesl/src/main/java/org/bigbluebutton/freeswitch/voice/freeswitch/actions/DeskShareRecordCommand.java @@ -0,0 +1,50 @@ +/** +* BigBlueButton open source conferencing system - http://www.bigbluebutton.org/ +* +* Copyright (c) 2015 BigBlueButton Inc. and by respective authors (see below). +* +* This program is free software; you can redistribute it and/or modify it under the +* terms of the GNU Lesser General Public License as published by the Free Software +* Foundation; either version 3.0 of the License, or (at your option) any later +* version. +* +* BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY +* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A +* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public License along +* with BigBlueButton; if not, see <http://www.gnu.org/licenses/>. +* +*/ +package org.bigbluebutton.freeswitch.voice.freeswitch.actions; + +import org.bigbluebutton.freeswitch.voice.events.ConferenceEventListener; +import org.freeswitch.esl.client.transport.message.EslMessage; + +public class DeskShareRecordCommand extends FreeswitchCommand { + + private String recordPath; + private boolean record; + + public DeskShareRecordCommand(String room, String requesterId, boolean record, String recordPath){ + super(room, requesterId); + this.recordPath = recordPath; + this.record = record; + } + + + @Override + public String getCommandArgs() { + String action = "norecord"; + if (record) + action = "record"; + + System.out.println("\n\n\n\n\n DESKSHARE RECORD " + record + "\n\n\n\n"); + return SPACE + getRoom() + SPACE + action + SPACE + recordPath; + } + + public void handleResponse(EslMessage response, ConferenceEventListener eventListener) { + //Test for Known Conference + System.out.println("\n\n\n\n\nLALALALLALA\n\n\n\n"); + } +} diff --git a/akka-bbb-fsesl/src/main/java/org/bigbluebutton/freeswitch/voice/freeswitch/actions/EjectAllUsersCommand.java b/akka-bbb-fsesl/src/main/java/org/bigbluebutton/freeswitch/voice/freeswitch/actions/EjectAllUsersCommand.java new file mode 100755 index 0000000000000000000000000000000000000000..4c24b28758e194176486cca1ba56181b4bb27304 --- /dev/null +++ b/akka-bbb-fsesl/src/main/java/org/bigbluebutton/freeswitch/voice/freeswitch/actions/EjectAllUsersCommand.java @@ -0,0 +1,31 @@ +/** +* BigBlueButton open source conferencing system - http://www.bigbluebutton.org/ +* +* Copyright (c) 2012 BigBlueButton Inc. and by respective authors (see below). +* +* This program is free software; you can redistribute it and/or modify it under the +* terms of the GNU Lesser General Public License as published by the Free Software +* Foundation; either version 3.0 of the License, or (at your option) any later +* version. +* +* BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY +* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A +* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public License along +* with BigBlueButton; if not, see <http://www.gnu.org/licenses/>. +* +*/ +package org.bigbluebutton.freeswitch.voice.freeswitch.actions; + +public class EjectAllUsersCommand extends FreeswitchCommand { + + public EjectAllUsersCommand(String room, String requesterId) { + super(room, requesterId); + } + + @Override + public String getCommandArgs() { + return room + " kick all"; + } +} diff --git a/akka-bbb-fsesl/src/main/java/org/bigbluebutton/freeswitch/voice/freeswitch/actions/EjectUserCommand.java b/akka-bbb-fsesl/src/main/java/org/bigbluebutton/freeswitch/voice/freeswitch/actions/EjectUserCommand.java new file mode 100755 index 0000000000000000000000000000000000000000..aa5315710f46092c0123423ebe9498258533fb5b --- /dev/null +++ b/akka-bbb-fsesl/src/main/java/org/bigbluebutton/freeswitch/voice/freeswitch/actions/EjectUserCommand.java @@ -0,0 +1,34 @@ +/** +* BigBlueButton open source conferencing system - http://www.bigbluebutton.org/ +* +* Copyright (c) 2012 BigBlueButton Inc. and by respective authors (see below). +* +* This program is free software; you can redistribute it and/or modify it under the +* terms of the GNU Lesser General Public License as published by the Free Software +* Foundation; either version 3.0 of the License, or (at your option) any later +* version. +* +* BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY +* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A +* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public License along +* with BigBlueButton; if not, see <http://www.gnu.org/licenses/>. +* +*/ +package org.bigbluebutton.freeswitch.voice.freeswitch.actions; + +public class EjectUserCommand extends FreeswitchCommand { + + private final String participant; + + public EjectUserCommand(String room, String participant, String requesterId) { + super(room, requesterId); + this.participant = participant; + } + + @Override + public String getCommandArgs() { + return room + " kick " + participant; + } +} diff --git a/akka-bbb-fsesl/src/main/java/org/bigbluebutton/freeswitch/voice/freeswitch/actions/FreeswitchCommand.java b/akka-bbb-fsesl/src/main/java/org/bigbluebutton/freeswitch/voice/freeswitch/actions/FreeswitchCommand.java new file mode 100755 index 0000000000000000000000000000000000000000..4efd29f95eb8905896494bf257d348b842f4c1c0 --- /dev/null +++ b/akka-bbb-fsesl/src/main/java/org/bigbluebutton/freeswitch/voice/freeswitch/actions/FreeswitchCommand.java @@ -0,0 +1,45 @@ +/** +* BigBlueButton open source conferencing system - http://www.bigbluebutton.org/ +* +* Copyright (c) 2012 BigBlueButton Inc. and by respective authors (see below). +* +* This program is free software; you can redistribute it and/or modify it under the +* terms of the GNU Lesser General Public License as published by the Free Software +* Foundation; either version 3.0 of the License, or (at your option) any later +* version. +* +* BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY +* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A +* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public License along +* with BigBlueButton; if not, see <http://www.gnu.org/licenses/>. +* +*/ +package org.bigbluebutton.freeswitch.voice.freeswitch.actions; + +public abstract class FreeswitchCommand { + public static final String SPACE = " "; + + protected final String room; + protected final String requesterId; + + public FreeswitchCommand(String room, String requesterId) { + this.room = room; + this.requesterId = requesterId; + } + + public String getCommand() { + return "conference"; //conference is default, override if needed. + } + + public abstract String getCommandArgs(); + + public String getRoom() { + return room; + } + + public String getRequesterId() { + return requesterId; + } +} diff --git a/akka-bbb-fsesl/src/main/java/org/bigbluebutton/freeswitch/voice/freeswitch/actions/GetAllUsersCommand.java b/akka-bbb-fsesl/src/main/java/org/bigbluebutton/freeswitch/voice/freeswitch/actions/GetAllUsersCommand.java new file mode 100755 index 0000000000000000000000000000000000000000..f4f1aab7a0452623823aeb13314734c5812c520c --- /dev/null +++ b/akka-bbb-fsesl/src/main/java/org/bigbluebutton/freeswitch/voice/freeswitch/actions/GetAllUsersCommand.java @@ -0,0 +1,115 @@ +/** +* BigBlueButton open source conferencing system - http://www.bigbluebutton.org/ +* +* Copyright (c) 2012 BigBlueButton Inc. and by respective authors (see below). +* +* This program is free software; you can redistribute it and/or modify it under the +* terms of the GNU Lesser General Public License as published by the Free Software +* Foundation; either version 3.0 of the License, or (at your option) any later +* version. +* +* BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY +* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A +* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public License along +* with BigBlueButton; if not, see <http://www.gnu.org/licenses/>. +* +*/ +package org.bigbluebutton.freeswitch.voice.freeswitch.actions; + +import org.freeswitch.esl.client.transport.message.EslMessage; +import org.apache.commons.lang3.StringUtils; +import org.bigbluebutton.freeswitch.voice.events.ConferenceEventListener; +import org.bigbluebutton.freeswitch.voice.events.VoiceUserJoinedEvent; +import org.bigbluebutton.freeswitch.voice.freeswitch.response.ConferenceMember; +import org.bigbluebutton.freeswitch.voice.freeswitch.response.XMLResponseConferenceListParser; + +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.parsers.SAXParser; +import javax.xml.parsers.SAXParserFactory; + +import org.xml.sax.SAXException; + +public class GetAllUsersCommand extends FreeswitchCommand { + + public GetAllUsersCommand(String room, String requesterId) { + super(room, requesterId); + } + + @Override + public String getCommandArgs() { + return getRoom() + SPACE + "xml_list"; + } + + private static final Pattern CALLERNAME_PATTERN = Pattern.compile("(.*)-bbbID-(.*)$"); + + public void handleResponse(EslMessage response, ConferenceEventListener eventListener) { + + //Test for Known Conference + + String firstLine = response.getBodyLines().get(0); + + //E.g. Conference 85115 not found + + if(!firstLine.startsWith("<?xml")) { +// System.out.println("Not XML: [{}]", firstLine); + return; + } + + + XMLResponseConferenceListParser confXML = new XMLResponseConferenceListParser(); + + //get a factory + SAXParserFactory spf = SAXParserFactory.newInstance(); + try { + + //get a new instance of parser + SAXParser sp = spf.newSAXParser(); + + //Hack turning body lines back into string then to ByteStream.... BLAH! + + String responseBody = StringUtils.join(response.getBodyLines(), "\n"); + + //http://mark.koli.ch/2009/02/resolving-orgxmlsaxsaxparseexception-content-is-not-allowed-in-prolog.html + //This Sux! + responseBody = responseBody.trim().replaceFirst("^([\\W]+)<","<"); + + ByteArrayInputStream bs = new ByteArrayInputStream(responseBody.getBytes()); + sp.parse(bs, confXML); + + //Maybe move this to XMLResponseConferenceListParser, sendConfrenceEvents ? + VoiceUserJoinedEvent pj; + + for(ConferenceMember member : confXML.getConferenceList()) { + //Foreach found member in conference create a JoinedEvent + String callerId = member.getCallerId(); + String callerIdName = member.getCallerIdName(); + String voiceUserId = callerIdName; + + Matcher matcher = CALLERNAME_PATTERN.matcher(callerIdName); + if (matcher.matches()) { + voiceUserId = matcher.group(1).trim(); + callerIdName = matcher.group(2).trim(); + } + + pj = new VoiceUserJoinedEvent(voiceUserId, member.getId().toString(), confXML.getConferenceRoom(), + callerId, callerIdName, member.getMuted(), member.getSpeaking(), null); + eventListener.handleConferenceEvent(pj); + } + + }catch(SAXException se) { +// System.out.println("Cannot parse repsonce. ", se); + }catch(ParserConfigurationException pce) { +// System.out.println("ParserConfigurationException. ", pce); + }catch (IOException ie) { +// System.out.println("Cannot parse repsonce. IO Exception. ", ie); + } + } + +} diff --git a/akka-bbb-fsesl/src/main/java/org/bigbluebutton/freeswitch/voice/freeswitch/actions/MuteUserCommand.java b/akka-bbb-fsesl/src/main/java/org/bigbluebutton/freeswitch/voice/freeswitch/actions/MuteUserCommand.java new file mode 100755 index 0000000000000000000000000000000000000000..e015535302b1db91db33e5467eb050c51ed9aa9c --- /dev/null +++ b/akka-bbb-fsesl/src/main/java/org/bigbluebutton/freeswitch/voice/freeswitch/actions/MuteUserCommand.java @@ -0,0 +1,40 @@ +/** +* BigBlueButton open source conferencing system - http://www.bigbluebutton.org/ +* +* Copyright (c) 2012 BigBlueButton Inc. and by respective authors (see below). +* +* This program is free software; you can redistribute it and/or modify it under the +* terms of the GNU Lesser General Public License as published by the Free Software +* Foundation; either version 3.0 of the License, or (at your option) any later +* version. +* +* BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY +* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A +* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public License along +* with BigBlueButton; if not, see <http://www.gnu.org/licenses/>. +* +*/ +package org.bigbluebutton.freeswitch.voice.freeswitch.actions; + +public class MuteUserCommand extends FreeswitchCommand { + + private final String participant; + private final Boolean mute; + + public MuteUserCommand(String room, String participant, Boolean mute, String requesterId) { + super(room, requesterId); + this.participant = participant; + this.mute = mute; + } + + @Override + public String getCommandArgs() { + String action = "unmute"; + if (mute) action = "mute"; + + return room + SPACE + action + SPACE + participant; + } + +} diff --git a/akka-bbb-fsesl/src/main/java/org/bigbluebutton/freeswitch/voice/freeswitch/actions/RecordConferenceCommand.java b/akka-bbb-fsesl/src/main/java/org/bigbluebutton/freeswitch/voice/freeswitch/actions/RecordConferenceCommand.java new file mode 100755 index 0000000000000000000000000000000000000000..ab2bd64c1ca7bc8244c7eb2f4371a01e2fb5a6f0 --- /dev/null +++ b/akka-bbb-fsesl/src/main/java/org/bigbluebutton/freeswitch/voice/freeswitch/actions/RecordConferenceCommand.java @@ -0,0 +1,50 @@ +/** +* BigBlueButton open source conferencing system - http://www.bigbluebutton.org/ +* +* Copyright (c) 2012 BigBlueButton Inc. and by respective authors (see below). +* +* This program is free software; you can redistribute it and/or modify it under the +* terms of the GNU Lesser General Public License as published by the Free Software +* Foundation; either version 3.0 of the License, or (at your option) any later +* version. +* +* BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY +* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A +* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public License along +* with BigBlueButton; if not, see <http://www.gnu.org/licenses/>. +* +*/ +package org.bigbluebutton.freeswitch.voice.freeswitch.actions; + +import org.bigbluebutton.freeswitch.voice.events.ConferenceEventListener; +import org.freeswitch.esl.client.transport.message.EslMessage; + +public class RecordConferenceCommand extends FreeswitchCommand { + + private boolean record; + private String recordPath; + + public RecordConferenceCommand(String room, String requesterId, boolean record, String recordPath){ + super(room, requesterId); + this.record = record; + this.recordPath = recordPath; + } + + + @Override + public String getCommandArgs() { + String action = "norecord"; + if (record) + action = "record"; + + return SPACE + getRoom() + SPACE + action + SPACE + recordPath; + } + + public void handleResponse(EslMessage response, ConferenceEventListener eventListener) { + + //Test for Known Conference + + } +} diff --git a/akka-bbb-fsesl/src/main/java/org/bigbluebutton/freeswitch/voice/freeswitch/actions/TransferUserToMeetingCommand.java b/akka-bbb-fsesl/src/main/java/org/bigbluebutton/freeswitch/voice/freeswitch/actions/TransferUserToMeetingCommand.java new file mode 100644 index 0000000000000000000000000000000000000000..c182dbc8ccc89f85e0b2f6672d14ab774a20e7fb --- /dev/null +++ b/akka-bbb-fsesl/src/main/java/org/bigbluebutton/freeswitch/voice/freeswitch/actions/TransferUserToMeetingCommand.java @@ -0,0 +1,41 @@ +/** + * BigBlueButton open source conferencing system - http://www.bigbluebutton.org/ + * + * Copyright (c) 2012 BigBlueButton Inc. and by respective authors (see below). + * + * This program is free software; you can redistribute it and/or modify it under the + * terms of the GNU Lesser General Public License as published by the Free Software + * Foundation; either version 3.0 of the License, or (at your option) any later + * version. + * + * BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A + * PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License along + * with BigBlueButton; if not, see <http://www.gnu.org/licenses/>. + * + */ + +package org.bigbluebutton.freeswitch.voice.freeswitch.actions; + +public class TransferUserToMeetingCommand extends FreeswitchCommand { + + private final String targetRoom; + private final String participant; + private final String audioProfile; + + public TransferUserToMeetingCommand(String room, String targetRoom, + String participant, String profile, String requesterId) { + super(room, requesterId); + this.targetRoom = targetRoom; + this.participant = participant; + this.audioProfile = profile; + } + + @Override + public String getCommandArgs() { + return room + SPACE + "transfer" + SPACE + targetRoom + "@" + + this.audioProfile + SPACE + participant; + } +} diff --git a/akka-bbb-fsesl/src/main/java/org/bigbluebutton/freeswitch/voice/freeswitch/response/ConferenceMember.java b/akka-bbb-fsesl/src/main/java/org/bigbluebutton/freeswitch/voice/freeswitch/response/ConferenceMember.java new file mode 100755 index 0000000000000000000000000000000000000000..915a265217c61fb67848443b6291bf64a57c2194 --- /dev/null +++ b/akka-bbb-fsesl/src/main/java/org/bigbluebutton/freeswitch/voice/freeswitch/response/ConferenceMember.java @@ -0,0 +1,88 @@ +/** +* BigBlueButton open source conferencing system - http://www.bigbluebutton.org/ +* +* Copyright (c) 2012 BigBlueButton Inc. and by respective authors (see below). +* +* This program is free software; you can redistribute it and/or modify it under the +* terms of the GNU Lesser General Public License as published by the Free Software +* Foundation; either version 3.0 of the License, or (at your option) any later +* version. +* +* BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY +* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A +* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public License along +* with BigBlueButton; if not, see <http://www.gnu.org/licenses/>. +* +*/ + +package org.bigbluebutton.freeswitch.voice.freeswitch.response; + +/** + * + * @author leif + */ +public class ConferenceMember { + + protected Integer memberId; + protected ConferenceMemberFlags flags; + protected String uuid; + protected String callerIdName; + protected String callerId; + protected Integer joinTime; + protected Integer lastTalking; + + public Integer getId() { + return memberId; + } + + public ConferenceMemberFlags getFlags() { + return flags; + } + + public String getCallerId() { + return callerId; + } + + public String getCallerIdName() { + return callerIdName; + } + + public boolean getMuted() { + return flags.getIsMuted(); + } + + public boolean getSpeaking() { + return flags.getIsSpeaking(); + } + + public void setFlags(ConferenceMemberFlags flags) { + this.flags = flags; + } + + public void setId(int parseInt) { + memberId = parseInt; + } + + public void setUUID(String tempVal) { + this.uuid = tempVal; + } + + public void setCallerIdName(String tempVal) { + this.callerIdName = tempVal; + } + + public void setCallerId(String tempVal) { + this.callerId = tempVal; + } + + public void setJoinTime(int parseInt) { + this.joinTime = parseInt; + } + + void setLastTalking(int parseInt) { + this.lastTalking = parseInt; + } + +} diff --git a/akka-bbb-fsesl/src/main/java/org/bigbluebutton/freeswitch/voice/freeswitch/response/ConferenceMemberFlags.java b/akka-bbb-fsesl/src/main/java/org/bigbluebutton/freeswitch/voice/freeswitch/response/ConferenceMemberFlags.java new file mode 100755 index 0000000000000000000000000000000000000000..f571f5da4fcf96bbad076b9c75d8a513f2773a9d --- /dev/null +++ b/akka-bbb-fsesl/src/main/java/org/bigbluebutton/freeswitch/voice/freeswitch/response/ConferenceMemberFlags.java @@ -0,0 +1,54 @@ +/** +* BigBlueButton open source conferencing system - http://www.bigbluebutton.org/ +* +* Copyright (c) 2012 BigBlueButton Inc. and by respective authors (see below). +* +* This program is free software; you can redistribute it and/or modify it under the +* terms of the GNU Lesser General Public License as published by the Free Software +* Foundation; either version 3.0 of the License, or (at your option) any later +* version. +* +* BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY +* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A +* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public License along +* with BigBlueButton; if not, see <http://www.gnu.org/licenses/>. +* +*/ + +package org.bigbluebutton.freeswitch.voice.freeswitch.response; + +/** + * + * @author leif + */ +public class ConferenceMemberFlags { + //private boolean canHear = false; + private boolean canSpeak = false; + private boolean talking = false; + //private boolean hasVideo = false; + //private boolean hasFloor = false; + //private boolean isModerator = false; + //private boolean endConference = false; + + boolean getIsSpeaking() { + return talking; + } + + boolean getIsMuted() { + if(canSpeak == true) { + return false; + } + return true; + } + + void setCanSpeak(String tempVal) { + canSpeak = tempVal.equals("true") ? true : false; + } + + void setTalking(String tempVal) { + talking = tempVal.equals("true") ? true : false; + } + +} diff --git a/akka-bbb-fsesl/src/main/java/org/bigbluebutton/freeswitch/voice/freeswitch/response/XMLResponseConferenceListParser.java b/akka-bbb-fsesl/src/main/java/org/bigbluebutton/freeswitch/voice/freeswitch/response/XMLResponseConferenceListParser.java new file mode 100755 index 0000000000000000000000000000000000000000..397e7ce42ab764bc9eb105b59ad9745a44fb940f --- /dev/null +++ b/akka-bbb-fsesl/src/main/java/org/bigbluebutton/freeswitch/voice/freeswitch/response/XMLResponseConferenceListParser.java @@ -0,0 +1,158 @@ +/** +* BigBlueButton open source conferencing system - http://www.bigbluebutton.org/ +* +* Copyright (c) 2012 BigBlueButton Inc. and by respective authors (see below). +* +* This program is free software; you can redistribute it and/or modify it under the +* terms of the GNU Lesser General Public License as published by the Free Software +* Foundation; either version 3.0 of the License, or (at your option) any later +* version. +* +* BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY +* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A +* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public License along +* with BigBlueButton; if not, see <http://www.gnu.org/licenses/>. +* +*/ +package org.bigbluebutton.freeswitch.voice.freeswitch.response; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import org.xml.sax.Attributes; +import org.xml.sax.SAXException; +import org.xml.sax.helpers.DefaultHandler; + +/** + * + * @author leif + */ +public class XMLResponseConferenceListParser extends DefaultHandler { + private List<ConferenceMember> myConfrenceMembers; + private String tempVal; + private ConferenceMember tempMember; + private ConferenceMemberFlags tempFlags; + private String room; + private boolean inFlags = false; + + public XMLResponseConferenceListParser() { + myConfrenceMembers = new ArrayList<ConferenceMember>(); + } + + public String getConferenceRoom() { + return room; + } + + public void printConferneceMemebers() { + Iterator<ConferenceMember> it = myConfrenceMembers.iterator(); + while(it.hasNext()) { + + } + } + + public List<ConferenceMember> getConferenceList() { + return myConfrenceMembers; + } + + /* +<?xml version="1.0"?> +<conferences> + <conference name="3001-192.168.1.10" member-count="1" rate="8000" running="true" answered="true" enforce_min="true" dynamic="true"> + <members> + <member> + <id>6</id> + <flags> + <can_hear>true</can_hear> + <can_speak>true</can_speak> + <talking>false</talking> + <has_video>false</has_video> + <has_floor>true</has_floor> + <is_moderator>false</is_moderator> + <end_conference>false</end_conference> + </flags> + <uuid>3a16f061-0df6-45d5-b401-d8e977e08a5c</uuid> + <caller_id_name>1001</caller_id_name> + <caller_id_number>1001</caller_id_number> + <join_time>65</join_time> + <last_talking>4</last_talking> + </member> + </members> + </conference> +</conferences> + + */ + + + //SAX Event Handlers + @Override + public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException { + //reset + inFlags = false; + tempVal = ""; + if(qName.equalsIgnoreCase("member")) { + //create a new instance of ConferenceMember + tempMember = new ConferenceMember(); + } + + if(qName.equalsIgnoreCase("flags")) { + //create a new instance of ConferenceMember + tempFlags = new ConferenceMemberFlags(); + inFlags = true; + } + + if(qName.equalsIgnoreCase("conference")) { + room = attributes.getValue("name"); + } + } + + + @Override + public void characters(char[] ch, int start, int length) throws SAXException { + tempVal = new String(ch,start,length); + } + + @Override + public void endElement(String uri, String localName, String qName) throws SAXException { + + if(qName.equalsIgnoreCase("member")) { + //add it to the list + myConfrenceMembers.add(tempMember); + }else if(qName.equalsIgnoreCase("flags")) { + tempMember.setFlags(tempFlags); + inFlags = false; + }else if(inFlags) { + if (qName.equalsIgnoreCase("can_speak")) { + tempFlags.setCanSpeak(tempVal); + }else if (qName.equalsIgnoreCase("talking")) { + tempFlags.setTalking(tempVal); + } + }else if (qName.equalsIgnoreCase("id")) { + try { + tempMember.setId(Integer.parseInt(tempVal)); + } catch(NumberFormatException nfe) { + + } + }else if (qName.equalsIgnoreCase("uuid")) { + tempMember.setUUID(tempVal); + }else if (qName.equalsIgnoreCase("caller_id_name")) { + tempMember.setCallerIdName(tempVal); + }else if (qName.equalsIgnoreCase("caller_id_number")) { + tempMember.setCallerId(tempVal); + }else if (qName.equalsIgnoreCase("join_time")) { + try { + tempMember.setJoinTime(Integer.parseInt(tempVal)); + } catch(NumberFormatException nfe) { + + } + }else if (qName.equalsIgnoreCase("last_talking")) { + try { + tempMember.setLastTalking(Integer.parseInt(tempVal)); + } catch(NumberFormatException nfe) { + + } + } + + } +} diff --git a/akka-bbb-fsesl/src/main/scala/org/bigbluebutton/freeswitch/VoiceConferenceService.scala b/akka-bbb-fsesl/src/main/scala/org/bigbluebutton/freeswitch/VoiceConferenceService.scala new file mode 100755 index 0000000000000000000000000000000000000000..42e63944c3c5e174951e8da61f3ce957ba28130c --- /dev/null +++ b/akka-bbb-fsesl/src/main/scala/org/bigbluebutton/freeswitch/VoiceConferenceService.scala @@ -0,0 +1,115 @@ +package org.bigbluebutton.freeswitch + +import org.bigbluebutton.SystemConfiguration +import org.bigbluebutton.freeswitch.voice.IVoiceConferenceService +import org.bigbluebutton.endpoint.redis.RedisPublisher +import org.bigbluebutton.common.messages.DeskShareStartedEventMessage +import org.bigbluebutton.common.messages.DeskShareStoppedEventMessage +import org.bigbluebutton.common.messages.DeskShareRTMPBroadcastStartedEventMessage +import org.bigbluebutton.common.messages.DeskShareRTMPBroadcastStoppedEventMessage +import org.bigbluebutton.common2.messages.{ BbbCommonEnvCoreMsg, BbbCoreEnvelope } +import org.bigbluebutton.common2.messages.voiceconf._ +import org.bigbluebutton.common2.util.JsonUtil + +class VoiceConferenceService(sender: RedisPublisher) extends IVoiceConferenceService with SystemConfiguration { + + def voiceConfRecordingStarted(voiceConfId: String, recordStream: String, recording: java.lang.Boolean, timestamp: String) { + val header = BbbCoreVoiceConfHeader(RecordingStartedVoiceConfEvtMsg.NAME, voiceConfId) + val body = RecordingStartedVoiceConfEvtMsgBody(voiceConfId, recordStream, recording.booleanValue(), timestamp) + val envelope = BbbCoreEnvelope(RecordingStartedVoiceConfEvtMsg.NAME, Map("voiceConf" -> voiceConfId)) + + val msg = new RecordingStartedVoiceConfEvtMsg(header, body) + val msgEvent = BbbCommonEnvCoreMsg(envelope, msg) + + val json = JsonUtil.toJson(msgEvent) + sender.publish(fromVoiceConfRedisChannel, json) + } + + def userJoinedVoiceConf(voiceConfId: String, voiceUserId: String, userId: String, callerIdName: String, + callerIdNum: String, muted: java.lang.Boolean, talking: java.lang.Boolean, avatarURL: String) { + println("******** FreeswitchConferenceService received voiceUserJoined vui=[" + + userId + "] wui=[" + voiceUserId + "]") + + val header = BbbCoreVoiceConfHeader(UserJoinedVoiceConfEvtMsg.NAME, voiceConfId) + val body = UserJoinedVoiceConfEvtMsgBody(voiceConfId, voiceUserId, userId, callerIdName, callerIdNum, + muted.booleanValue(), talking.booleanValue(), avatarURL) + val envelope = BbbCoreEnvelope(UserJoinedVoiceConfEvtMsg.NAME, Map("voiceConf" -> voiceConfId)) + + val msg = new UserJoinedVoiceConfEvtMsg(header, body) + val msgEvent = BbbCommonEnvCoreMsg(envelope, msg) + + val json = JsonUtil.toJson(msgEvent) + sender.publish(fromVoiceConfRedisChannel, json) + } + + def userLeftVoiceConf(voiceConfId: String, voiceUserId: String) { + println("******** FreeswitchConferenceService received voiceUserLeft vui=[" + voiceUserId + "] conference=[" + voiceConfId + "]") + + val header = BbbCoreVoiceConfHeader(UserLeftVoiceConfEvtMsg.NAME, voiceConfId) + val body = UserLeftVoiceConfEvtMsgBody(voiceConfId, voiceUserId) + val envelope = BbbCoreEnvelope(UserLeftVoiceConfEvtMsg.NAME, Map("voiceConf" -> voiceConfId)) + + val msg = new UserLeftVoiceConfEvtMsg(header, body) + val msgEvent = BbbCommonEnvCoreMsg(envelope, msg) + + val json = JsonUtil.toJson(msgEvent) + sender.publish(fromVoiceConfRedisChannel, json) + } + + def userLockedInVoiceConf(voiceConfId: String, voiceUserId: String, locked: java.lang.Boolean) { + + } + + def userMutedInVoiceConf(voiceConfId: String, voiceUserId: String, muted: java.lang.Boolean) { + println("******** FreeswitchConferenceService received voiceUserMuted vui=[" + voiceUserId + "] muted=[" + muted + "]") + + val header = BbbCoreVoiceConfHeader(UserMutedInVoiceConfEvtMsg.NAME, voiceConfId) + val body = UserMutedInVoiceConfEvtMsgBody(voiceConfId, voiceUserId, muted.booleanValue()) + val envelope = BbbCoreEnvelope(UserMutedInVoiceConfEvtMsg.NAME, Map("voiceConf" -> voiceConfId)) + + val msg = new UserMutedInVoiceConfEvtMsg(header, body) + val msgEvent = BbbCommonEnvCoreMsg(envelope, msg) + + val json = JsonUtil.toJson(msgEvent) + sender.publish(fromVoiceConfRedisChannel, json) + } + + def userTalkingInVoiceConf(voiceConfId: String, voiceUserId: String, talking: java.lang.Boolean) { + println("******** FreeswitchConferenceService received voiceUserTalking vui=[" + voiceUserId + "] talking=[" + talking + "]") + + val header = BbbCoreVoiceConfHeader(UserTalkingInVoiceConfEvtMsg.NAME, voiceConfId) + val body = UserTalkingInVoiceConfEvtMsgBody(voiceConfId, voiceUserId, talking.booleanValue()) + val envelope = BbbCoreEnvelope(UserTalkingInVoiceConfEvtMsg.NAME, Map("voiceConf" -> voiceConfId)) + + val msg = new UserTalkingInVoiceConfEvtMsg(header, body) + val msgEvent = BbbCommonEnvCoreMsg(envelope, msg) + + val json = JsonUtil.toJson(msgEvent) + sender.publish(fromVoiceConfRedisChannel, json) + } + + def deskShareStarted(voiceConfId: String, callerIdNum: String, callerIdName: String) { + println("******** FreeswitchConferenceService send deskShareStarted to BBB " + voiceConfId) + val msg = new DeskShareStartedEventMessage(voiceConfId, callerIdNum, callerIdName) + sender.publish(fromVoiceConfRedisChannel, msg.toJson()) + } + + def deskShareEnded(voiceConfId: String, callerIdNum: String, callerIdName: String) { + println("******** FreeswitchConferenceService send deskShareStopped to BBB " + voiceConfId) + val msg = new DeskShareStoppedEventMessage(voiceConfId, callerIdNum, callerIdName) + sender.publish(fromVoiceConfRedisChannel, msg.toJson()) + } + + def deskShareRTMPBroadcastStarted(voiceConfId: String, streamname: String, vw: java.lang.Integer, vh: java.lang.Integer, timestamp: String) { + println("******** FreeswitchConferenceService send deskShareRTMPBroadcastStarted to BBB " + voiceConfId) + val msg = new DeskShareRTMPBroadcastStartedEventMessage(voiceConfId, streamname, vw, vh, timestamp) + sender.publish(fromVoiceConfRedisChannel, msg.toJson()) + } + + def deskShareRTMPBroadcastStopped(voiceConfId: String, streamname: String, vw: java.lang.Integer, vh: java.lang.Integer, timestamp: String) { + println("******** FreeswitchConferenceService send deskShareRTMPBroadcastStopped to BBB " + voiceConfId) + val msg = new DeskShareRTMPBroadcastStoppedEventMessage(voiceConfId, streamname, vw, vh, timestamp) + sender.publish(fromVoiceConfRedisChannel, msg.toJson()) + } + +}