Commit 7070fbdb authored by daryl herzmann's avatar daryl herzmann

Merge pull request #160 from deleolajide/ofmeet-version-0.0.8

ofmeet plugin version 0.0.8
parents 109311ed 00c94594
......@@ -49,6 +49,15 @@
Openfire Meetings Plugin Changelog
</h1>
<p><b>0.0.8</b> -- Jan 16th, 2015</p>
<ul>
<li>Fixed race condition causing focus xmpp connection to fail</li>
<li>Increased response timeout for focus</li>
<li>Improved error handling for read-only user providers like LDAP</li>
<li>Disable SIP gateway with a property (org.jitsi.videobridge.ofmeet.sip.enabled)</li>
</ul>
<p><b>0.0.7</b> -- Jan 5th, 2015</p>
<ul>
......
......@@ -5,8 +5,8 @@
<name>Openfire Meetings</name>
<description>Provides high quality, scalable video conferences using Jitsi Meet and Jitsi Videobridge</description>
<author>Ignite Realtime</author>
<version>0.0.7</version>
<date>01/05/2014</date>
<version>0.0.8</version>
<date>01/16/2015</date>
<minServerVersion>3.9.9</minServerVersion>
<adminconsole>
......
......@@ -3015,13 +3015,13 @@ Candy.View.Observer = function(self, $) {
* (Object) args - {message, roomJid}
*/
self.Message = function(event, args) {
if (args.message.type === "subject") {
if (args && args.message && args.message.type === "subject") {
if (!Candy.View.Pane.Chat.rooms[args.roomJid]) {
Candy.View.Pane.Room.init(args.roomJid, args.message.name);
Candy.View.Pane.Room.show(args.roomJid);
}
Candy.View.Pane.Room.setSubject(args.roomJid, args.message.body);
} else if (args.message.type === "info") {
} else if (args && args.message && args.message.type === "info") {
Candy.View.Pane.Chat.infoMessage(args.roomJid, args.message.body);
} else {
// Initialize room if it's a message for a new private user chat
......
......@@ -324,10 +324,11 @@ public final class XMPPServlet extends WebSocketServlet
if (wsSession != null && wsSession.isOpen() && !"".equals( packet.trim() ) )
{
try {
Log.debug( digest + " : Delivered : " + packet );
wsSession.getRemote().sendString(packet);
Log.debug( digest + " : Delivered : \n" + packet );
wsSession.getRemote().sendStringByFuture(packet);
} catch (Exception e) {
Log.error("XMPPWebSocket deliver " + e);
Log.warn( digest + " : Could not deliver : \n" + packet );
}
}
}
......
......@@ -458,7 +458,7 @@ public class XmppProtocolProvider
connection.sendPacket(packet);
//FIXME: retry allocation on timeout
Packet response = packetCollector.nextResult(20000);
Packet response = packetCollector.nextResult(60000); // BAO
packetCollector.cancel();
......
/*
* Jicofo, the Jitsi Conference Focus.
*
* Distributable under LGPL license.
* See terms of license at gnu.org.
*/
package org.jitsi.impl.protocol.xmpp.extensions;
import org.jitsi.util.*;
import org.jivesoftware.smack.packet.*;
/**
* IQ sent to the focus in order to get the URL used for authentication with
* external system.
*
* @author Pawel Domas
*/
public class AuthUrlIQ
extends IQ
{
public static final String NAMESPACE = ConferenceIq.NAMESPACE;
public static final String ELEMENT_NAME = "auth-url";
/**
* The name of the attribute that holds authentication URL value.
*/
public static final String URL_ATTRIBUTE_NAME = "url";
/**
* The name of the attribute that carries the name of conference room
* which will be used as authentication context.
*/
public static final String ROOM_NAME_ATTR_NAME = "room";
/**
* The URL used for authentication with external system.
*/
private String url;
/**
* The conference room name used as a context for authentication.
* muc_room_name@muc.server.name
*/
private String room;
@Override
public String getChildElementXML()
{
StringBuilder xml = new StringBuilder();
xml.append('<').append(ELEMENT_NAME);
xml.append(" xmlns='").append(NAMESPACE).append("' ");
printAttributes(xml);
xml.append("/>");
return xml.toString();
}
/**
* Prints attributes in XML format to given <tt>StringBuilder</tt>.
* @param out the <tt>StringBuilder</tt> instance used to construct XML
* representation of this element.
*/
void printAttributes(StringBuilder out)
{
if (!StringUtils.isNullOrEmpty(url))
{
out.append(URL_ATTRIBUTE_NAME)
.append("='").append(url).append("' ");
}
if (!StringUtils.isNullOrEmpty(room))
{
out.append(ROOM_NAME_ATTR_NAME)
.append("='").append(room).append("' ");
}
}
/**
* Returns the value of {@link #URL_ATTRIBUTE_NAME} attribute.
*/
public String getUrl()
{
return url;
}
/**
* Sets the value of {@link #URL_ATTRIBUTE_NAME} attribute.
* @param url authentication URL value to be set on this IQ instance.
*/
public void setUrl(String url)
{
this.url = url;
}
/**
* Returns the value of {@link #ROOM_NAME_ATTR_NAME} attribute.
*/
public String getRoom()
{
return room;
}
/**
* Sets the value of {@link #ROOM_NAME_ATTR_NAME} attribute.
* @param room the name of MUC room to be set on this instance.
*/
public void setRoom(String room)
{
this.room = room;
}
}
/*
* Jicofo, the Jitsi Conference Focus.
*
* Distributable under LGPL license.
* See terms of license at gnu.org.
*/
package org.jitsi.impl.protocol.xmpp.extensions;
import net.java.sip.communicator.impl.protocol.jabber.extensions.*;
/**
* Packet extension sent in focus MUC presence to notify users about JVB failure.
*
* @author Pawel Domas
*/
public class BridgeIsDownPacketExt
extends AbstractPacketExtension
{
private final static String ELEMENT_NAME = "bridgeIsDown";
public BridgeIsDownPacketExt()
{
super("", ELEMENT_NAME);
}
}
/*
* Jicofo, the Jitsi Conference Focus.
*
* Distributable under LGPL license.
* See terms of license at gnu.org.
*/
package org.jitsi.impl.protocol.xmpp.extensions;
import net.java.sip.communicator.impl.protocol.jabber.extensions.*;
import org.jitsi.util.*;
import org.jivesoftware.smack.packet.*;
import java.util.*;
/**
* FIXME: move to Jitsi ?
*
* The IQ used by Jitsi Meet conference participant to contact the focus and ask
* it to handle the conference in some multi user chat room.
*
* @author Pawel Domas
*/
public class ConferenceIq
extends IQ
{
/**
* Focus namespace.
*/
public final static String NAMESPACE = "http://jitsi.org/protocol/focus";
/**
* XML element name for the <tt>ConferenceIq</tt>.
*/
public static final String ELEMENT_NAME = "conference";
/**
* The name of the attribute that stores the name of multi user chat room
* that is hosting Jitsi Meet conference.
*/
public static final String ROOM_ATTR_NAME = "room";
/**
* The name of the attribute that indicates if the focus has already joined
* the room(otherwise users might decide not to join yet).
*/
public static final String READY_ATTR_NAME = "ready";
/**
* The name of the attribute that tells to the user what is
* the jid of the focus user.
*/
public static final String FOCUS_JID_ATTR_NAME = "focusjid";
/**
* MUC room name hosting Jitsi Meet conference.
*/
private String room;
/**
* Indicates if the focus is already in the MUC room and conference is ready
* to be joined.
*/
private Boolean ready;
/**
* The JID of authenticated focus user.
*/
private String focusJid;
/**
* The list of configuration properties that are contained in this IQ.
*/
private List<Property> properties = new ArrayList<Property>();
/**
* Prints attributes in XML format to given <tt>StringBuilder</tt>.
* @param out the <tt>StringBuilder</tt> instance used to construct XML
* representation of this element.
*/
void printAttributes(StringBuilder out)
{
out.append(ROOM_ATTR_NAME)
.append("=")
.append("'").append(room).append("' ");
if (ready != null)
{
out.append(READY_ATTR_NAME)
.append("=")
.append("'").append(ready).append("' ");
}
if (!StringUtils.isNullOrEmpty(focusJid))
{
out.append(FOCUS_JID_ATTR_NAME)
.append("=")
.append("'").append(focusJid).append("' ");
}
}
/**
* {@inheritDoc}
*/
@Override
public String getChildElementXML()
{
StringBuilder xml = new StringBuilder();
xml.append('<').append(ELEMENT_NAME);
xml.append(" xmlns='").append(NAMESPACE).append("' ");
printAttributes(xml);
Collection<PacketExtension> extensions = getExtensions();
if (extensions.size() > 0 || properties.size() > 0)
{
xml.append(">");
for (PacketExtension extension : extensions)
{
xml.append(extension.toXML());
}
for (Property property : properties)
{
xml.append(property.toXML());
}
xml.append("</").append(ELEMENT_NAME).append(">");
}
else
{
xml.append("/>");
}
return xml.toString();
}
/**
* Returns the value of {@link #ready} attribute.
*/
public Boolean isReady()
{
return ready;
}
/**
* Sets the value of {@link #ready} attribute of this <tt>ConferenceIq</tt>.
* @param ready the value to be set as {@link #ready} attribute value.
*/
public void setReady(Boolean ready)
{
this.ready = ready;
}
/**
* Returns the value of {@link #room} attribute of this
* <tt>ConferenceIq</tt>.
*/
public String getRoom()
{
return room;
}
/**
* Sets the {@link #room} attribute of this <tt>ConferenceIq</tt>.
* @param room the value to be set as {@link #room} attribute value.
*/
public void setRoom(String room)
{
this.room = room;
}
/**
* Returns the value of {@link #FOCUS_JID_ATTR_NAME} held by this IQ.
*/
public String getFocusJid()
{
return focusJid;
}
/**
* Sets the value for the focus JID attribute.
* @param focusJid a string with the JID of focus user('username@domain').
*/
public void setFocusJid(String focusJid)
{
this.focusJid = focusJid;
}
/**
* Adds property packet extension to this IQ.
* @param property the instance <tt>Property</tt> to be added to this IQ.
*/
public void addProperty(Property property)
{
properties.add(property);
}
/**
* Returns the list of properties contained in this IQ.
* @return list of <tt>Property</tt> contained in this IQ.
*/
public List<Property> getProperties()
{
return properties;
}
/**
* Converts list of properties contained in this IQ into the name to value
* mapping.
* @return the map of property names to values as strings.
*/
public Map<String, String> getPropertiesMap()
{
Map<String, String> properties= new HashMap<String, String>();
for (Property property : this.properties)
{
properties.put(property.getName(), property.getValue());
}
return properties;
}
/**
* Packet extension for configuration properties.
*/
public static class Property extends AbstractPacketExtension
{
/**
* The name of property XML element.
*/
public static final String ELEMENT_NAME = "property";
/**
* The name of 'name' property attribute.
*/
public static final String NAME_ATTR_NAME = "name";
/**
* The name of 'value' property attribute.
*/
public static final String VALUE_ATTR_NAME = "value";
/**
* Creates new empty <tt>Property</tt> instance.
*/
public Property()
{
super(null, ELEMENT_NAME);
}
/**
* Creates new <tt>Property</tt> instance initialized with given
* <tt>name</tt> and <tt>value</tt> values.
*
* @param name a string that will be the name of new property.
* @param value a string value for new property.
*/
public Property(String name, String value)
{
this();
setName(name);
setValue(value);
}
/**
* Sets the name of this property.
* @param name a string that will be the name of this property.
*/
public void setName(String name)
{
setAttribute(NAME_ATTR_NAME, name);
}
/**
* Returns the name of this property.
*/
public String getName()
{
return getAttributeAsString(NAME_ATTR_NAME);
}
/**
* Sets the value of this property.
* @param value a string value for new property.
*/
public void setValue(String value)
{
setAttribute(VALUE_ATTR_NAME, value);
}
/**
* Returns the value of this property.
*/
public String getValue()
{
return getAttributeAsString(VALUE_ATTR_NAME);
}
}
}
/*
* Jicofo, the Jitsi Conference Focus.
*
* Distributable under LGPL license.
* See terms of license at gnu.org.
*/
package org.jitsi.impl.protocol.xmpp.extensions;
import org.jitsi.util.*;
import org.jivesoftware.smack.packet.*;
import org.jivesoftware.smack.provider.*;
import org.xmlpull.v1.*;
/**
* Provider handles parsing of {@link ConferenceIq} and {@link AuthUrlIQ}
* stanzas and converting objects back to their XML representation.
*
* @author Pawel Domas
*/
public class ConferenceIqProvider
implements IQProvider
{
/**
* Creates new instance of <tt>ConferenceIqProvider</tt>.
*/
public ConferenceIqProvider()
{
ProviderManager providerManager = ProviderManager.getInstance();
// <conference>
providerManager.addIQProvider(
ConferenceIq.ELEMENT_NAME, ConferenceIq.NAMESPACE, this);
// <auth-url>
providerManager.addIQProvider(
AuthUrlIQ.ELEMENT_NAME, AuthUrlIQ.NAMESPACE, this);
}
/**
* {@inheritDoc}
*/
@Override
public IQ parseIQ(XmlPullParser parser)
throws Exception
{
String namespace = parser.getNamespace();
// Check the namespace
if (!ConferenceIq.NAMESPACE.equals(namespace))
{
return null;
}
String rootElement = parser.getName();
ConferenceIq iq = null;
AuthUrlIQ authUrlIQ = null;
if (ConferenceIq.ELEMENT_NAME.equals(rootElement))
{
iq = new ConferenceIq();
String room
= parser.getAttributeValue("", ConferenceIq.ROOM_ATTR_NAME);
iq.setRoom(room);
String ready
= parser.getAttributeValue("", ConferenceIq.READY_ATTR_NAME);
if (!StringUtils.isNullOrEmpty(ready))
{
iq.setReady(Boolean.valueOf(ready));
}
String focusJid
= parser.getAttributeValue(
"", ConferenceIq.FOCUS_JID_ATTR_NAME);
if (!StringUtils.isNullOrEmpty(focusJid))
{
iq.setFocusJid(focusJid);
}
}
else if (AuthUrlIQ.ELEMENT_NAME.equals(rootElement))
{
authUrlIQ = new AuthUrlIQ();
String url = parser.getAttributeValue(
"", AuthUrlIQ.URL_ATTRIBUTE_NAME);
if (!StringUtils.isNullOrEmpty(url))
{
authUrlIQ.setUrl(url);
}
String room = parser.getAttributeValue(
"", AuthUrlIQ.ROOM_NAME_ATTR_NAME);
if (!StringUtils.isNullOrEmpty(room))
{
authUrlIQ.setRoom(room);
}
}
else
{
return null;
}
ConferenceIq.Property property = null;
boolean done = false;
while (!done)
{
switch (parser.next())
{
case XmlPullParser.END_TAG:
{
String name = parser.getName();
if (rootElement.equals(name))
{
done = true;
}
else if (ConferenceIq.Property.ELEMENT_NAME.equals(name))
{
if (iq != null && property != null)
{
iq.addProperty(property);
property = null;
}
}
break;
}
case XmlPullParser.START_TAG:
{
String name = parser.getName();
if (ConferenceIq.Property.ELEMENT_NAME.equals(name))
{
property = new ConferenceIq.Property();
// Name
String propName
= parser.getAttributeValue(
"",
ConferenceIq.Property.NAME_ATTR_NAME);
if (!StringUtils.isNullOrEmpty(propName))
{
property.setName(propName);
}
// Value
String propValue
= parser.getAttributeValue(
"",
ConferenceIq.Property.VALUE_ATTR_NAME);
if (!StringUtils.isNullOrEmpty(propValue))
{
property.setValue(propValue);
}
}
}
}
}
return iq != null ? iq : authUrlIQ;
}
}
/*
* Jicofo, the Jitsi Conference Focus.
*
* Distributable under LGPL license.
* See terms of license at gnu.org.
*/
package org.jitsi.jicofo.auth;
import net.java.sip.communicator.util.*;
import java.util.*;
import java.util.concurrent.*;
/**
* Common class for {@link AuthenticationAuthority} implementations.
*
* @author Pawel Domas
*/
public abstract class AbstractAuthAuthority
implements AuthenticationAuthority
{
/**
* The logger.
*/
private final static Logger logger
= Logger.getLogger(AbstractAuthAuthority.class);
/**
* The list of registered {@link AuthenticationListener}s.
*/
private List<AuthenticationListener> authenticationListeners
= new CopyOnWriteArrayList<AuthenticationListener>();
/**
* Registers to the list of <tt>AuthenticationListener</tt>s.
* @param l the <tt>AuthenticationListener</tt> to be added to listeners
* list.
*/
@Override
public void addAuthenticationListener(AuthenticationListener l)
{
if (!authenticationListeners.contains(l))
{
authenticationListeners.add(l);
}
}
/**
* Unregisters from the list of <tt>AuthenticationListener</tt>s.
* @param l the <tt>AuthenticationListener</tt> that will be removed from
* authentication listeners list.
*/
@Override
public void removeAuthenticationListener(AuthenticationListener l)
{
authenticationListeners.remove(l);
}
protected void notifyUserAuthenticated(String userJid, String identity)
{
logger.info("Jid " + userJid + " authenticated as: " + identity);
for (AuthenticationListener l : authenticationListeners)
{
l.jidAuthenticated(userJid, identity);
}
}
}
/*
* Jicofo, the Jitsi Conference Focus.
*
* Distributable under LGPL license.
* See terms of license at gnu.org.
*/
package org.jitsi.jicofo.auth;
/**
* FIXME work in progress
* This interface is intended to encapsulate authorization method like
* Shibboleth, OAuth or XMPP domain.
*
* @author Pawel Domas
*/
public interface AuthenticationAuthority
{
/**
* Checks if given user is allowed to create the room.
* @param peerJid the Jabber ID of the user.
* @param roomName the name of the conference room to be checked.
* @return <tt>true</tt> if it's OK to create the room for given name on
* behalf of verified user or <tt>false</tt> otherwise.
*/
boolean isAllowedToCreateRoom(String peerJid, String roomName);
/**
* Registers to the list of <tt>AuthenticationListener</tt>s.
* @param l the <tt>AuthenticationListener</tt> to be added to listeners
* list.
*/
void addAuthenticationListener(AuthenticationListener l);
/**
* Unregisters from the list of <tt>AuthenticationListener</tt>s.
* @param l the <tt>AuthenticationListener</tt> that will be removed from
* authentication listeners list.
*/
void removeAuthenticationListener(AuthenticationListener l);
/**
* Returns <tt>true</tt> if user is authenticated in given conference room.
* @param jabberID the Jabber ID of the user to be verified.
* @param roomName conference room name which is the context of
* authentication.
*/
boolean isUserAuthenticated(String jabberID, String roomName);
String createAuthenticationUrl(String peerFullJid, String roomName);
/**
* Returns <tt>true</tt> if this is external authentication method that
* requires user to visit authentication URL.
*/
boolean isExternal();
void start();
void stop();
}
/*
* Jicofo, the Jitsi Conference Focus.
*
* Distributable under LGPL license.
* See terms of license at gnu.org.
*/
package org.jitsi.jicofo.auth;
/**
* Interface used to listen to authentication notification fired by
* {@link AuthenticationAuthority}.
*
* @author Pawel Domas
*/
public interface AuthenticationListener
{
/**
* Called by {@link AuthenticationAuthority} when the user identified by
* given <tt>userJid</tt> gets confirmed identity by external authentication
* component.
*
* @param userJid the real user JID(not MUC JID which can be faked).
* @param authenticatedIdentity the identity of the user confirmed by
* external authentication component.
*/
void jidAuthenticated(String userJid, String authenticatedIdentity);
}
/*
* Jicofo, the Jitsi Conference Focus.
*
* Distributable under LGPL license.
* See terms of license at gnu.org.
*/
package org.jitsi.jicofo.auth;
/**
* Class used by {@link ShibbolethAuthAuthority} to track authentication state of
* conference participants. It contains user JID, name of the conference room
* for which authentication is valid, authentication identity assigned by
* external authentication system and creation timestamp use to expire
* pre-authentications(authentication for which the room has not been created
* yet).
*
* @author Pawel Domas
*/
public class AuthenticationState
{
private final String userJid;
private final String roomName;
private final String authenticatedIdentity;
private final long authTimestamp = System.currentTimeMillis();
/**
* Creates new {@link AuthenticationState}.
* @param userJid the Jabber ID of authenticated user.
* @param roomName the name of conference room for which this
* authentication is valid.
* @param authenticatedIdentity the identity assigned by external system
* that will be bound to <tt>userJid</tt>.
*/
public AuthenticationState(String userJid,
String roomName,
String authenticatedIdentity)
{
this.userJid = userJid;
this.roomName = roomName;
this.authenticatedIdentity = authenticatedIdentity;
}
/**
* Returns the Jabber ID of authenticated user.
*/
public String getUserJid()
{
return userJid;
}
/**
* Returns the identity assigned by external authentication system.
*/
public String getAuthenticatedIdentity()
{
return authenticatedIdentity;
}
/**
* Returns conference room name for which this authentication is valid.
*/
public String getRoomName()
{
return roomName;
}
/**
* Creation timestamp of this instance.
*/
public long getAuthTimestamp()
{
return authTimestamp;
}
@Override
public String toString()
{
return "AuthState[jid=" + this.userJid + ", room="
+ this.roomName + ", id=" + authenticatedIdentity + "]@"
+ hashCode();
}
}
/*
* Jicofo, the Jitsi Conference Focus.
*
* Distributable under LGPL license.
* See terms of license at gnu.org.
*/
package org.jitsi.jicofo.auth;
/**
* Authentication token is used to identify authentication request. It also
* binds some resources related to authentication internally instead of
* exposing them as direct HTTP request parameters. Each token can be used
* only once to authenticate and they expire after {@link
* AuthAuthority#TOKEN_LIFETIME} if not used.
*
* @author Pawel Domas
*/
public class AuthenticationToken
{
private final long creationTimestamp;
private final String token;
private final String userJid;
private final String roomName;
/**
* Creates new {@link AuthenticationToken} for given parameters.
* @param token generated random token string which will server as token
* value.
* @param userJid the Jabber ID of the user associated with
* authentication request.
* @param roomName the name of conference room which is a context for
* authentication request identified by new token instance.
*/
public AuthenticationToken(String token, String userJid, String roomName)
{
if (token == null)
{
throw new NullPointerException("token");
}
if (userJid == null)
{
throw new NullPointerException("userJid");
}
if (roomName == null)
{
throw new NullPointerException("roomName");
}
this.token = token;
this.userJid = userJid;
this.roomName = roomName;
creationTimestamp = System.currentTimeMillis();
}
/**
* Returns creation timestamp of this token instance.
* @return timestamp in milliseconds obtained using {@link
* System#currentTimeMillis()}.
*/
public long getCreationTimestamp()
{
return creationTimestamp;
}
/**
* Returns conference room name for which this token can be used for
* authentication.
*/
public String getRoomName()
{
return roomName;
}
/**
* Returns string token value of this instance.
*/
public String getToken()
{
return token;
}
/**
* Returns Jabber ID of the user associated with this token instance.
*/
public String getUserJid()
{
return userJid;
}
}
/*
* Jicofo, the Jitsi Conference Focus.
*
* Distributable under LGPL license.
* See terms of license at gnu.org.
*/
package org.jitsi.jicofo.auth;
/**
* XMPP domain authentication authority that authorizes user who are logged
* in on specified domain.
*
* FIXME move to separate package
*
* @author Pawel Domas
*/
public class XMPPDomainAuthAuthority
extends AbstractAuthAuthority
{
/**
* Trusted domain for which users are considered authenticated.
*/
private final String domain;
public XMPPDomainAuthAuthority(String domain)
{
this.domain = domain;
}
private boolean verifyJid(String fullJid)
{
String bareJid = fullJid.substring(0, fullJid.indexOf("/"));
return bareJid.endsWith("@" + domain);
}
@Override
public boolean isAllowedToCreateRoom(String peerJid, String roomName)
{
return verifyJid(peerJid);
}
@Override
public boolean isUserAuthenticated(String jabberID, String roomName)
{
return verifyJid(jabberID);
}
@Override
public String createAuthenticationUrl(String peerFullJid, String roomName)
{
return "null";
}
@Override
public boolean isExternal()
{
return false;
}
@Override
public void start()
{
}
@Override
public void stop()
{
}
}
......@@ -51,8 +51,10 @@ public class JicofoPlugin
String hostName = JiveGlobals.getProperty("org.jitsi.videobridge.nat.harvester.public.address", XMPPServer.getInstance().getServerInfo().getHostname());
String domain = XMPPServer.getInstance().getServerInfo().getXMPPDomain();
String focusUserJid = JiveGlobals.getProperty("org.jitsi.videobridge.ofmeet.focus.user.jid", "focus@"+domain);
String focusUserPassword = JiveGlobals.getProperty("org.jitsi.videobridge.ofmeet.focus.user.password", "focus");
String focusUserPassword = JiveGlobals.getProperty("org.jitsi.videobridge.ofmeet.focus.user.password", null);
if (focusUserPassword != null)
{
Log.info("JicofoPlugin - using focus " + focusUserJid + ":" + hostName + "/" + focusUserPassword);
System.setProperty("org.jitsi.videobridge.ofmeet.audio.mixer", JiveGlobals.getProperty("org.jitsi.videobridge.ofmeet.audio.mixer", "false"));
......@@ -69,6 +71,10 @@ public class JicofoPlugin
FocusComponent component = new FocusComponent(false);
componentManager.addComponent(subdomain, component);
added = true;
} else {
Log.error("Focus user not setup. password missing " + focusUserJid);
}
}
catch (Exception ce)
{
......
......@@ -95,7 +95,15 @@ public class CallControlComponent extends AbstractComponent
properties.setProperty("gov.nist.javax.sip.SERVER_LOG", logDir + "sip_server.log");
properties.setProperty("gov.nist.javax.sip.DEBUG_LOG", logDir + "sip_debug.log");
if (JiveGlobals.getBooleanProperty("org.jitsi.videobridge.ofmeet.sip.enabled", true))
{
Log.info("CallControlComponent - enabling SIP gateway ");
sipService = new SipService(properties);
} else {
Log.info("CallControlComponent -enabling SIP gateway");
}
}
@Override protected String[] discoInfoFeatureNamespaces()
......@@ -128,7 +136,7 @@ public class CallControlComponent extends AbstractComponent
callSessions.clear();
sipService.stop();
if (sipService != null) sipService.stop();
}
public void recordCall(Conference conference, String token, String state)
......@@ -173,7 +181,7 @@ public class CallControlComponent extends AbstractComponent
mediaStream.setRTPTranslator(content.getRTPTranslator());
}
content.createRtpChannel(null);
content.createRtpChannel(null, null, null);
CallSession cs = new CallSession(mediaStream, hostname, this, callId, focusJid, confJid);
callSessions.put(callId, cs);
......@@ -319,7 +327,7 @@ public class CallControlComponent extends AbstractComponent
mediaStream.setRTPTranslator(content.getRTPTranslator());
}
content.createRtpChannel(null);
content.createRtpChannel(null, null, null);
String callId = Long.toHexString(System.currentTimeMillis());
session = new CallSession(mediaStream, hostname, this, callId, conference.getFocus(), confJID);
......
......@@ -15,8 +15,8 @@ import java.util.*;
/**
* Class encapsulates configuration properties for Jitsi Meet conference that
* are attached to create conference request
* {@link org.jitsi.jicofo.xmpp.ConferenceIq}. Options are configured in
* 'config.js' file of Jitsi Meet Java Script application.
* {@link org.jitsi.impl.protocol.xmpp.extensions.ConferenceIq}. Options are
* configured in 'config.js' file of Jitsi Meet Java Script application.
*
* @author Pawel Domas
*/
......@@ -33,7 +33,13 @@ public class JitsiMeetConfig
* instance. It will be used when all auto-detected instances fail(or if we
* fail to detect any bridges at all).
*/
public static final String BRIDGE_N_PNAME = "bridge";
public static final String BRIDGE_PNAME = "bridge";
/**
* The name of the configuration property used to configure Jigasi(SIP
* gateway) instance.
*/
public static final String SIP_GATEWAY_PNAME = "call_control";
/**
* The name of channel last N configuration property. Should be non-negative
......@@ -84,7 +90,16 @@ public class JitsiMeetConfig
*/
public String getPreConfiguredVideobridge()
{
return properties.get(BRIDGE_N_PNAME);
return properties.get(BRIDGE_PNAME);
}
/**
* Returns pre-configured XMPP address of SIP gateway or <tt>null</tt> if
* no info was passed in the config.
*/
public String getPreConfiguredSipGateway()
{
return properties.get(SIP_GATEWAY_PNAME);
}
/**
......
......@@ -70,11 +70,12 @@ public class Config extends HttpServlet
String conferences = "[";
try {
boolean clientControl = XMPPServer.getInstance().getPluginManager().getPlugin("clientControl") != null || XMPPServer.getInstance().getPluginManager().getPlugin("clientcontrol") != null;
if (clientControl)
{
try {
final Collection<Bookmark> bookmarks = BookmarkManager.getBookmarks();
for (Bookmark bookmark : bookmarks)
......@@ -90,11 +91,11 @@ public class Config extends HttpServlet
}
}
}
}
} catch (Exception e) {
}
}
conferences = conferences + "]";
......@@ -107,8 +108,8 @@ public class Config extends HttpServlet
String iceServers = JiveGlobals.getProperty("org.jitsi.videobridge.ofmeet.iceservers", "");
String resolution = JiveGlobals.getProperty("org.jitsi.videobridge.ofmeet.resolution", "360");
String audioMixer = JiveGlobals.getProperty("org.jitsi.videobridge.ofmeet.audio.mixer", "false");
String audioBandwidth = JiveGlobals.getProperty("org.jitsi.videobridge.ofmeet.audio.bandwidth", "64");
String videoBandwidth = JiveGlobals.getProperty("org.jitsi.videobridge.ofmeet.video.bandwidth", "512");
String audioBandwidth = JiveGlobals.getProperty("org.jitsi.videobridge.ofmeet.audio.bandwidth", "128");
String videoBandwidth = JiveGlobals.getProperty("org.jitsi.videobridge.ofmeet.video.bandwidth", "2048");
String useNicks = JiveGlobals.getProperty("org.jitsi.videobridge.ofmeet.usenicks", "false");
String useIPv6 = JiveGlobals.getProperty("org.jitsi.videobridge.ofmeet.useipv6", "false");
String useStunTurn = JiveGlobals.getProperty("org.jitsi.videobridge.ofmeet.use.stunturn", "false");
......@@ -131,12 +132,19 @@ public class Config extends HttpServlet
String logStats = JiveGlobals.getProperty("org.jitsi.videobridge.ofmeet.enable.stats.logging", "false");
String focusUserJid = JiveGlobals.getProperty("org.jitsi.videobridge.ofmeet.focus.user.jid", "focus@"+domain);
String callControl = "'ofmeet-call-control." + domain + "'";
if (JiveGlobals.getBooleanProperty("org.jitsi.videobridge.ofmeet.sip.enabled", true) == false)
{
callControl = "null";
}
out.println("var config = {");
out.println(" hosts: {");
out.println(" domain: '" + domain + "',");
out.println(" muc: 'conference." + domain + "',");
out.println(" bridge: 'ofmeet-jitsi-videobridge." + domain + "',");
out.println(" call_control: 'ofmeet-call-control." + domain + "',");
out.println(" call_control: " + callControl + ",");
out.println(" focus: 'ofmeet-focus." + domain + "',");
out.println(" },");
out.println(" getroomnode: function (path)");
......@@ -193,7 +201,7 @@ public class Config extends HttpServlet
}
catch(Exception e) {
Log.info("Config doGet Error", e);
Log.error("Config doGet Error", e);
}
}
......@@ -211,7 +219,7 @@ public class Config extends HttpServlet
}
catch(Exception e)
{
Log.info("Config writeHeader Error", e);
Log.error("Config writeHeader Error", e);
}
}
......
......@@ -83,7 +83,7 @@ public class OfMeetPlugin implements Plugin, ClusterEventListener {
return jitsiPlugin;
}
public void initializePlugin(PluginManager manager, File pluginDirectory) {
public void initializePlugin(final PluginManager manager, final File pluginDirectory) {
ContextHandlerCollection contexts = HttpBindManager.getInstance().getContexts();
......@@ -96,7 +96,7 @@ public class OfMeetPlugin implements Plugin, ClusterEventListener {
jitsiPlugin = new PluginImpl();
jitsiPlugin.initializePlugin(manager, pluginDirectory);
Log.info("OfMeet Plugin - Initialize jitsi sip gateway ");
Log.info("OfMeet Plugin - Initialize SIP gateway ");
jigasiPlugin = new JigasiPlugin();
jigasiPlugin.initializePlugin(manager, pluginDirectory);
......@@ -107,7 +107,6 @@ public class OfMeetPlugin implements Plugin, ClusterEventListener {
String domain = XMPPServer.getInstance().getServerInfo().getXMPPDomain();
String userName = "focus";
String focusUserJid = userName + "@" + domain;
String focusUserPassword = "focus-password-" + System.currentTimeMillis();
try {
userManager.getUser(userName);
......@@ -116,6 +115,9 @@ public class OfMeetPlugin implements Plugin, ClusterEventListener {
Log.info("OfMeet Plugin - Setup focus user " + focusUserJid);
String focusUserPassword = "focus-password-" + System.currentTimeMillis();
try {
userManager.createUser(userName, focusUserPassword, "Openfire Meetings Focus User", focusUserJid);
JiveGlobals.setProperty("org.jitsi.videobridge.ofmeet.focus.user.jid", focusUserJid);
......@@ -126,9 +128,21 @@ public class OfMeetPlugin implements Plugin, ClusterEventListener {
allowedJIDs.add(new JID(focusUserJid));
mucService.addSysadmins(allowedJIDs);
}
catch (Exception e1) {
Log.error("Could NOT create focus user", e1);
}
}
new Timer().schedule(new TimerTask()
{
@Override public void run()
{
jicofoPlugin = new JicofoPlugin();
jicofoPlugin.initializePlugin(manager, pluginDirectory);
}
}, 5000);
ClusterManager.addListener(this);
......
......@@ -770,7 +770,7 @@ JingleSession.prototype.getStats = function (interval) {
JingleSession.prototype.setBandwidth = function (sdp)
{
// remove existing bandwidth lines
sdp = sdp.replace( /b=AS([^\r\n]+\r\n)/g , '');
//sdp = sdp.replace( /b=AS([^\r\n]+\r\n)/g , '');
// audio bandwidth
sdp = sdp.replace( /a=mid:audio\r\n/g , 'a=mid:audio\r\nb=AS:' + config.audioBandwidth + '\r\n');
......
......@@ -319,7 +319,7 @@ SimulcastReceiver.prototype._updateRemoteMaps = function (lines) {
this._remoteMaps.msid2ssrc = {};
var self = this;
if (remoteVideoSources.groups && remoteVideoSources.groups.length !== 0) {
if (remoteVideoSources && remoteVideoSources.groups && remoteVideoSources.groups.length !== 0) {
remoteVideoSources.groups.forEach(function (group) {
if (group.semantics === 'SIM' && group.ssrcs && group.ssrcs.length !== 0) {
quality = 0;
......
......@@ -1968,7 +1968,7 @@ var VideoLayout = (function (my) {
}
var resolutionValue = null;
if(this.resolution)
if(this.resolution && this.jid != null)
{
var keys = Object.keys(this.resolution);
if(keys.length == 1)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment