Commit 00c94594 authored by Dele Olajide's avatar Dele Olajide

ofmeet plugin version 0.0.8

Fixed race condition causing focus xmpp connection to fail
Increased response timeout for focus
Improved error handling for read-only user providers like LDAP
Disable SIP gateway with a property
(org.jitsi.videobridge.ofmeet.sip.enabled)
Latest jitsi-videobridge server code
parent ea81dc86
......@@ -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,24 +51,30 @@ 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");
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"));
System.setProperty("net.java.sip.communicator.service.gui.ALWAYS_TRUST_MODE_ENABLED", "true");
System.setProperty(FocusManager.HOSTNAME_PNAME, hostName);
System.setProperty(FocusManager.XMPP_DOMAIN_PNAME, domain);
System.setProperty(FocusManager.FOCUS_USER_DOMAIN_PNAME, domain);
System.setProperty(FocusManager.FOCUS_USER_NAME_PNAME, (new JID(focusUserJid)).getNode());
System.setProperty(FocusManager.FOCUS_USER_PASSWORD_PNAME, focusUserPassword);
ComponentManager componentManager = ComponentManagerFactory.getComponentManager();
String subdomain = "ofmeet-focus";
FocusComponent component = new FocusComponent(false);
componentManager.addComponent(subdomain, component);
added = true;
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"));
System.setProperty("net.java.sip.communicator.service.gui.ALWAYS_TRUST_MODE_ENABLED", "true");
System.setProperty(FocusManager.HOSTNAME_PNAME, hostName);
System.setProperty(FocusManager.XMPP_DOMAIN_PNAME, domain);
System.setProperty(FocusManager.FOCUS_USER_DOMAIN_PNAME, domain);
System.setProperty(FocusManager.FOCUS_USER_NAME_PNAME, (new JID(focusUserJid)).getNode());
System.setProperty(FocusManager.FOCUS_USER_PASSWORD_PNAME, focusUserPassword);
ComponentManager componentManager = ComponentManagerFactory.getComponentManager();
String subdomain = "ofmeet-focus";
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");
sipService = new SipService(properties);
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 = "[";
boolean clientControl = XMPPServer.getInstance().getPluginManager().getPlugin("clientControl") != null || XMPPServer.getInstance().getPluginManager().getPlugin("clientcontrol") != null;
try {
if (clientControl)
{
try {
boolean clientControl = XMPPServer.getInstance().getPluginManager().getPlugin("clientControl") != null || XMPPServer.getInstance().getPluginManager().getPlugin("clientcontrol") != null;
if (clientControl)
{
final Collection<Bookmark> bookmarks = BookmarkManager.getBookmarks();
for (Bookmark bookmark : bookmarks)
......@@ -90,10 +91,10 @@ public class Config extends HttpServlet
}
}
}
}
} catch (Exception e) {
} 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,19 +115,34 @@ public class OfMeetPlugin implements Plugin, ClusterEventListener {
Log.info("OfMeet Plugin - Setup focus user " + focusUserJid);
userManager.createUser(userName, focusUserPassword, "Openfire Meetings Focus User", focusUserJid);
String focusUserPassword = "focus-password-" + System.currentTimeMillis();
JiveGlobals.setProperty("org.jitsi.videobridge.ofmeet.focus.user.jid", focusUserJid);
JiveGlobals.setProperty("org.jitsi.videobridge.ofmeet.focus.user.password", focusUserPassword);
try {
userManager.createUser(userName, focusUserPassword, "Openfire Meetings Focus User", focusUserJid);
JiveGlobals.setProperty("org.jitsi.videobridge.ofmeet.focus.user.jid", focusUserJid);
JiveGlobals.setProperty("org.jitsi.videobridge.ofmeet.focus.user.password", focusUserPassword);
MultiUserChatService mucService = XMPPServer.getInstance().getMultiUserChatManager().getMultiUserChatService("conference");
List<JID> allowedJIDs = new ArrayList<JID>();
allowedJIDs.add(new JID(focusUserJid));
mucService.addSysadmins(allowedJIDs);
}
catch (Exception e1) {
MultiUserChatService mucService = XMPPServer.getInstance().getMultiUserChatManager().getMultiUserChatService("conference");
List<JID> allowedJIDs = new ArrayList<JID>();
allowedJIDs.add(new JID(focusUserJid));
mucService.addSysadmins(allowedJIDs);
Log.error("Could NOT create focus user", e1);
}
}
jicofoPlugin = new JicofoPlugin();
jicofoPlugin.initializePlugin(manager, pluginDirectory);
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