From c373dc42e83ad07299e90f74e34f6d7dfdb1cf8c Mon Sep 17 00:00:00 2001
From: Richard Alam <ritzalam@gmail.com>
Date: Tue, 1 Oct 2019 11:36:06 -0700
Subject: [PATCH]  For eject of voice conference user  - Sometimes ejecting
 voice conf users using "conference vconf kick all" doesn't work. We need to  
  forcefully eject the user by using "uuid_kill uuid".

---
 .../freeswitch/FreeswitchApplication.java     |  4 +-
 .../actions/CheckIfConfIsRunningCommand.java  | 21 ++++++++--
 .../actions/ForceEjectUserCommand.java        | 38 +++++++++++++++++++
 3 files changed, 59 insertions(+), 4 deletions(-)
 create mode 100755 akka-bbb-fsesl/src/main/java/org/bigbluebutton/freeswitch/voice/freeswitch/actions/ForceEjectUserCommand.java

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
index ead6c0740c..74ccdf05f1 100755
--- 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
@@ -168,7 +168,9 @@ public class FreeswitchApplication implements  IDelayedCommandListener{
           EjectAllUsersCommand cmd = (EjectAllUsersCommand) command;
           manager.ejectAll(cmd);
 
-          CheckIfConfIsRunningCommand command = new CheckIfConfIsRunningCommand(cmd.getRoom(), cmd.getRequesterId());
+          CheckIfConfIsRunningCommand command = new CheckIfConfIsRunningCommand(cmd.getRoom(),
+                  cmd.getRequesterId(),
+                  delayedCommandSenderService);
           delayedCommandSenderService.handleMessage(command, 5000);
         } else if (command instanceof TransferUserToMeetingCommand) {
           TransferUserToMeetingCommand cmd = (TransferUserToMeetingCommand) command;
diff --git a/akka-bbb-fsesl/src/main/java/org/bigbluebutton/freeswitch/voice/freeswitch/actions/CheckIfConfIsRunningCommand.java b/akka-bbb-fsesl/src/main/java/org/bigbluebutton/freeswitch/voice/freeswitch/actions/CheckIfConfIsRunningCommand.java
index badda5e404..a6f8e8e5f3 100755
--- a/akka-bbb-fsesl/src/main/java/org/bigbluebutton/freeswitch/voice/freeswitch/actions/CheckIfConfIsRunningCommand.java
+++ b/akka-bbb-fsesl/src/main/java/org/bigbluebutton/freeswitch/voice/freeswitch/actions/CheckIfConfIsRunningCommand.java
@@ -20,6 +20,7 @@ package org.bigbluebutton.freeswitch.voice.freeswitch.actions;
 
 import org.apache.commons.lang3.StringUtils;
 import org.bigbluebutton.freeswitch.voice.events.ConferenceEventListener;
+import org.bigbluebutton.freeswitch.voice.freeswitch.DelayedCommandSenderService;
 import org.bigbluebutton.freeswitch.voice.freeswitch.response.ConferenceMember;
 import org.bigbluebutton.freeswitch.voice.freeswitch.response.XMLResponseConferenceListParser;
 import org.freeswitch.esl.client.transport.message.EslMessage;
@@ -36,9 +37,11 @@ import java.util.regex.Matcher;
 
 public class CheckIfConfIsRunningCommand extends FreeswitchCommand {
     private static Logger log = LoggerFactory.getLogger(CheckIfConfIsRunningCommand.class);
+    private DelayedCommandSenderService delayedCommandSenderService;
 
-    public CheckIfConfIsRunningCommand(String room, String requesterId) {
+    public CheckIfConfIsRunningCommand(String room, String requesterId, DelayedCommandSenderService delayedCommandSenderService) {
             super(room, requesterId);
+            this.delayedCommandSenderService = delayedCommandSenderService;
     }
     
     @Override
@@ -94,12 +97,24 @@ public class CheckIfConfIsRunningCommand extends FreeswitchCommand {
                         String uuid = member.getUUID();
                         log.info("WARNING! User possibly stuck in conference. uuid=" + uuid
                                 + ",caller=" + callerIdName + ",callerId=" + callerId + ",conf=" + room);
-                    } else if ("recording_node".equals(member.getMemberType())) {
 
-                    }
+                        // We have stubborn users that cannot be ejected from the voice conference.
+                        // This results in the voice conference hanging around for potentially a long time.
+                        // Force ejection by killing their uuid. (ralam Oct 1, 2019)
+                        ForceEjectUserCommand forceEjectUserCommand = new ForceEjectUserCommand(getRoom(),
+                                member.getId().toString(),
+                                member.getUUID());
+                        delayedCommandSenderService.handleMessage(forceEjectUserCommand, 5000L);
 
+                    } else if ("recording_node".equals(member.getMemberType())) {
 
+                    }
                 }
+                // Check again if the conference is still running after ejecting the users. (ralam Oct. 1, 2019)
+                CheckIfConfIsRunningCommand command = new CheckIfConfIsRunningCommand(getRoom(),
+                        getRequesterId(),
+                        delayedCommandSenderService);
+                delayedCommandSenderService.handleMessage(command, 10000);
             } else {
                 log.info("INFO! Successfully ejected all users from conference {}.", room);
             }
diff --git a/akka-bbb-fsesl/src/main/java/org/bigbluebutton/freeswitch/voice/freeswitch/actions/ForceEjectUserCommand.java b/akka-bbb-fsesl/src/main/java/org/bigbluebutton/freeswitch/voice/freeswitch/actions/ForceEjectUserCommand.java
new file mode 100755
index 0000000000..1bfe15de98
--- /dev/null
+++ b/akka-bbb-fsesl/src/main/java/org/bigbluebutton/freeswitch/voice/freeswitch/actions/ForceEjectUserCommand.java
@@ -0,0 +1,38 @@
+package org.bigbluebutton.freeswitch.voice.freeswitch.actions;
+
+import com.google.gson.Gson;
+import org.bigbluebutton.freeswitch.voice.events.ConferenceEventListener;
+import org.freeswitch.esl.client.transport.message.EslMessage;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class ForceEjectUserCommand extends FreeswitchCommand {
+    private static Logger log = LoggerFactory.getLogger(ForceEjectUserCommand.class);
+
+    private final String voiceConf;
+    private final String userId;
+    private final String uuid;
+
+    public ForceEjectUserCommand(String voiceConf, String userId, String uuid) {
+        super(voiceConf, userId);
+        this.voiceConf = voiceConf;
+        this.userId = userId;
+        this.uuid = uuid;
+    }
+    @Override
+    public String getCommand() {
+        return "uuid_kill " + uuid;
+    }
+
+    @Override
+    public String getCommandArgs() {
+        log.debug("Force eject user " + userId + " from conf " + voiceConf + " by uuid_kill " + uuid);
+        return "";
+    }
+
+    public void handleResponse(EslMessage response, ConferenceEventListener eventListener) {
+        Gson gson = new Gson();
+        log.info(gson.toJson(response.getBodyLines()));
+
+    }
+}
-- 
GitLab