Commit c17251c4 authored by Dele Olajide's avatar Dele Olajide Committed by dele

Videobridge plugin - Adding support for rayo protocol

Rayo plugin - Adding support for colibri protocol

git-svn-id: http://svn.igniterealtime.org/svn/repos/openfire/trunk@13850 b35dd754-fafc-0310-a699-88a17e54d16e
parent 3a1c22fb
...@@ -5,12 +5,20 @@ import org.dom4j.Element; ...@@ -5,12 +5,20 @@ import org.dom4j.Element;
public class ColibriCommand extends AbstractVerbCommand { public class ColibriCommand extends AbstractVerbCommand {
private String videobridge; private String videobridge;
private Element conference; private String localRTPPort;
private String localRTCPPort;
private String remoteRTPPort;
private String remoteRTCPPort;
private String codec;
public ColibriCommand(String videobridge, Element conference) public ColibriCommand(String videobridge, String localRTPPort, String localRTCPPort, String remoteRTPPort, String remoteRTCPPort, String codec)
{ {
this.videobridge = videobridge; this.videobridge = videobridge;
this.conference = conference; this.localRTPPort = localRTPPort;
this.localRTCPPort = localRTCPPort;
this.remoteRTPPort = remoteRTPPort;
this.remoteRTCPPort = remoteRTCPPort;
this.codec = codec;
} }
public String getVideobridge() public String getVideobridge()
...@@ -18,8 +26,28 @@ public class ColibriCommand extends AbstractVerbCommand { ...@@ -18,8 +26,28 @@ public class ColibriCommand extends AbstractVerbCommand {
return this.videobridge; return this.videobridge;
} }
public Element getConference() public String getLocalRTPPort()
{ {
return this.conference; return this.localRTPPort;
}
public String getLocalRTCPPort()
{
return this.localRTCPPort;
}
public String getRemoteRTPPort()
{
return this.remoteRTPPort;
}
public String getRemoteRTCPPort()
{
return this.remoteRTCPPort;
}
public String getCodec()
{
return this.codec;
} }
} }
...@@ -31,7 +31,6 @@ public class ColibriProvider extends BaseProvider { ...@@ -31,7 +31,6 @@ public class ColibriProvider extends BaseProvider {
// ================================================================================ // ================================================================================
private static final Namespace NAMESPACE = new Namespace("", "urn:xmpp:rayo:colibri:1"); private static final Namespace NAMESPACE = new Namespace("", "urn:xmpp:rayo:colibri:1");
private static final QName COLIBRI_QNAME = new QName("colibri", NAMESPACE); private static final QName COLIBRI_QNAME = new QName("colibri", NAMESPACE);
@Override @Override
...@@ -46,9 +45,13 @@ public class ColibriProvider extends BaseProvider { ...@@ -46,9 +45,13 @@ public class ColibriProvider extends BaseProvider {
private Object buildColibriCommand(Element element) throws URISyntaxException private Object buildColibriCommand(Element element) throws URISyntaxException
{ {
String videobridge = element.attributeValue("videobridge"); String videobridge = element.attributeValue("videobridge");
Element conference = element.element("conference").createCopy(); String localRTPPort = element.attributeValue("localrtpport");
String localRTCPPort = element.attributeValue("localrtcpport");
String remoteRTPPort = element.attributeValue("remotertpport");
String remoteRTCPPort = element.attributeValue("remotertcpport");
String codec = element.attributeValue("codec");
ColibriCommand command = new ColibriCommand(videobridge, conference); ColibriCommand command = new ColibriCommand(videobridge, localRTPPort, localRTCPPort, remoteRTPPort, remoteRTCPPort, codec);
return command; return command;
} }
...@@ -60,10 +63,7 @@ public class ColibriProvider extends BaseProvider { ...@@ -60,10 +63,7 @@ public class ColibriProvider extends BaseProvider {
@Override @Override
protected void generateDocument(Object object, Document document) throws Exception { protected void generateDocument(Object object, Document document) throws Exception {
if (object instanceof ColibriCommand) { if (object instanceof ColibriOfferEvent) {
createColibriCommand((ColibriCommand) object, document);
} else if (object instanceof ColibriOfferEvent) {
createColibriOfferEvent((ColibriOfferEvent) object, document); createColibriOfferEvent((ColibriOfferEvent) object, document);
} else if (object instanceof AddSourceEvent) { } else if (object instanceof AddSourceEvent) {
...@@ -80,12 +80,6 @@ public class ColibriProvider extends BaseProvider { ...@@ -80,12 +80,6 @@ public class ColibriProvider extends BaseProvider {
} }
} }
private void createColibriCommand(ColibriCommand command, Document document) throws Exception
{
Element root = document.addElement(new QName("colibri", NAMESPACE));
root.addAttribute("videobridge", command.getVideobridge());
}
private void createColibriOfferEvent(ColibriOfferEvent event, Document document) private void createColibriOfferEvent(ColibriOfferEvent event, Document document)
{ {
Element root = document.addElement(new QName("offer", NAMESPACE)); Element root = document.addElement(new QName("offer", NAMESPACE));
......
/*
* Jitsi VideoBridge, OpenSource video conferencing.
*
* Distributable under LGPL license.
* See terms of license at gnu.org.
*/
package org.jitsi.videobridge.util;
import java.io.*;
import org.dom4j.*;
import org.dom4j.io.*;
import org.jivesoftware.smack.provider.*;
import org.xmlpull.v1.*;
import org.xmpp.packet.*;
/**
* Provides functionality which aids the manipulation of
* <tt>org.jivesoftware.smack.packet.IQ</tt> and <tt>org.xmpp.packet.IQ</tt>
* instances.
*
* @author Lyubomir Marinov
*/
public final class IQUtils
{
/**
* The <tt>XmlPullParserFactory</tt> instance which is to create
* <tt>XmlPullParser</tt> instances for the purposes of
* {@link #convert(org.xmpp.packet.IQ)}. Introduced as a shared instance in
* order to avoid unnecessary allocations.
*/
private static XmlPullParserFactory xmlPullParserFactory;
/**
* Converts a specific <tt>org.jivesoftware.smack.packet.IQ</tt> instance
* into a new <tt>org.xmpp.packet.iQ</tt> instance which represents the same
* stanza.
*
* @param smackIQ the <tt>org.jivesoftware.smack.packet.IQ</tt> instance to
* convert to a new <tt>org.xmpp.packet.IQ</tt> instance
* @return a new <tt>org.xmpp.packet.IQ</tt> instance which represents the
* same stanza as the specified <tt>smackIQ</tt>
* @throws Exception if anything goes wrong during the conversion
*/
public static org.xmpp.packet.IQ convert(
org.jivesoftware.smack.packet.IQ smackIQ)
throws Exception
{
String xml = smackIQ.getChildElementXML();
Element element = null;
if ((xml != null) && (xml.length() != 0))
{
SAXReader saxReader = new SAXReader();
Document document = saxReader.read(new StringReader(xml));
element = document.getRootElement();
}
org.xmpp.packet.IQ iq = new org.xmpp.packet.IQ();
String from = smackIQ.getFrom();
if ((from != null) && (from.length() != 0))
iq.setFrom(new JID(from));
iq.setID(smackIQ.getPacketID());
String to = smackIQ.getTo();
if ((to != null) && (to.length() != 0))
iq.setTo(new JID(to));
iq.setType(convert(smackIQ.getType()));
if (element != null)
iq.setChildElement(element);
return iq;
}
/**
* Converts a specific <tt>org.xmpp.packet.iQ</tt> instance into a new
* <tt>org.jivesoftware.smack.packet.IQ</tt> instance which represents the
* same stanza.
*
* @param iq the <tt>org.xmpp.packet.IQ</tt> instance to convert to a new
* <tt>org.jivesoftware.smack.packet.IQ</tt> instance
* @return a new <tt>org.jivesoftware.smack.packet.IQ</tt> instance which
* represents the same stanza as the specified <tt>iq</tt>
* @throws Exception if anything goes wrong during the conversion
*/
public static org.jivesoftware.smack.packet.IQ convert(
org.xmpp.packet.IQ iq)
throws Exception
{
Element element = iq.getChildElement();
IQProvider iqProvider
= (IQProvider)
ProviderManager.getInstance().getIQProvider(
element.getName(),
element.getNamespaceURI());
org.jivesoftware.smack.packet.IQ smackIQ = null;
if (iqProvider != null)
{
XmlPullParserFactory xmlPullParserFactory;
synchronized (IQUtils.class)
{
if (IQUtils.xmlPullParserFactory == null)
{
IQUtils.xmlPullParserFactory
= XmlPullParserFactory.newInstance();
IQUtils.xmlPullParserFactory.setNamespaceAware(true);
}
xmlPullParserFactory = IQUtils.xmlPullParserFactory;
}
XmlPullParser parser = xmlPullParserFactory.newPullParser();
parser.setInput(new StringReader(iq.toXML()));
int eventType = parser.next();
if (XmlPullParser.START_TAG == eventType)
{
String name = parser.getName();
if ("iq".equals(name))
{
eventType = parser.next();
if (XmlPullParser.START_TAG == eventType)
{
smackIQ = iqProvider.parseIQ(parser);
if (smackIQ != null)
{
eventType = parser.getEventType();
if (XmlPullParser.END_TAG != eventType)
{
throw new IllegalStateException(
Integer.toString(eventType)
+ " != XmlPullParser.END_TAG");
}
}
}
else
{
throw new IllegalStateException(
Integer.toString(eventType)
+ " != XmlPullParser.START_TAG");
}
}
else
throw new IllegalStateException(name + " != iq");
}
else
{
throw new IllegalStateException(
Integer.toString(eventType)
+ " != XmlPullParser.START_TAG");
}
}
if (smackIQ != null)
{
org.xmpp.packet.JID fromJID = iq.getFrom();
if (fromJID != null)
smackIQ.setFrom(fromJID.toString());
smackIQ.setPacketID(iq.getID());
org.xmpp.packet.JID toJID = iq.getTo();
if (toJID != null)
smackIQ.setTo(toJID.toString());
smackIQ.setType(convert(iq.getType()));
}
return smackIQ;
}
/**
* Converts an <tt>org.jivesoftware.smack.packet.IQ.Type</tt> value into an
* <tt>org.xmpp.packet.IQ.Type</tt> value which represents the same IQ type.
*
* @param smackType the <tt>org.jivesoftware.smack.packet.IQ.Type</tt> value
* to convert into an <tt>org.xmpp.packet.IQ.Type</tt> value
* @return an <tt>org.xmpp.packet.IQ.Type</tt> value which represents the
* same IQ type as the specified <tt>smackType</tt>
*/
public static org.xmpp.packet.IQ.Type convert(
org.jivesoftware.smack.packet.IQ.Type smackType)
{
return org.xmpp.packet.IQ.Type.valueOf(smackType.toString());
}
/**
* Converts an <tt>org.xmpp.packet.IQ.Type</tt> value into an
* <tt>org.jivesoftware.smack.packet.IQ.Type</tt> value which represents the
* same IQ type.
*
* @param type the <tt>org.xmpp.packet.IQ.Type</tt> value to convert into an
* <tt>org.jivesoftware.smack.packet.IQ.Type</tt> value
* @return an <tt>org.jivesoftware.smack.packet.IQ.Type</tt> value which
* represents the same IQ type as the specified <tt>type</tt>
*/
public static org.jivesoftware.smack.packet.IQ.Type convert(
org.xmpp.packet.IQ.Type type)
{
return org.jivesoftware.smack.packet.IQ.Type.fromString(type.name());
}
/** Prevents the initialization of new <tt>IQUtils</tt> instances. */
private IQUtils()
{
}
}
...@@ -375,6 +375,41 @@ Strophe.addConnectionPlugin('rayo', ...@@ -375,6 +375,41 @@ Strophe.addConnectionPlugin('rayo',
this._offhook(mixer, headers, function() this._offhook(mixer, headers, function()
{ {
that._dial(mixer, from, to, headers);
});
},
voicebridge: function(mixer, from, to, headers)
{
console.log('Rayo plugin voicebridge ' + mixer);
var that = this;
var iq = $iq({to: mixer + "@" + this._connection.domain, from: this._connection.jid, type: "get"}).c("join", {xmlns: Strophe.NS.RAYO_CORE, "mixer-name": mixer});
//console.log(iq.toString());
this._connection.sendIQ(iq, function(response)
{
that._dial(mixer, from, to, headers);
}, function(error) {
$('error', error).each(function()
{
var errorcode = $(this).attr('code');
if (that.callbacks && that.callbacks.onError) that.callbacks.onError("voicebridge failure " + errorcode);
});
});
},
_dial: function(mixer, from, to, headers)
{
//console.log('Rayo plugin _dial ' + from + " " + to);
//console.log(headers)
var that = this;
var iq = $iq({to: that._connection.domain, from: that._connection.jid, type: "get"}).c("dial", {xmlns: Strophe.NS.RAYO_CORE, to: to, from: from}); var iq = $iq({to: that._connection.domain, from: that._connection.jid, type: "get"}).c("dial", {xmlns: Strophe.NS.RAYO_CORE, to: to, from: from});
if (headers) if (headers)
...@@ -434,10 +469,8 @@ Strophe.addConnectionPlugin('rayo', ...@@ -434,10 +469,8 @@ Strophe.addConnectionPlugin('rayo',
that._onhook(); that._onhook();
}); });
});
}, },
_isOffhook: function() _isOffhook: function()
{ {
return this.localStream != null; return this.localStream != null;
......
...@@ -405,12 +405,10 @@ public class MemberReceiver implements MixDataSource, TreatmentDoneListener { ...@@ -405,12 +405,10 @@ public class MemberReceiver implements MixDataSource, TreatmentDoneListener {
int inChannels = myMediaInfo.getChannels(); int inChannels = myMediaInfo.getChannels();
if (cp.getPhoneNumber().indexOf("@") >= 0) { //if (cp.getPhoneNumber().indexOf("@") >= 0) {
ConferenceReceiver conferenceReceiver = ConferenceReceiver conferenceReceiver = conferenceManager.getConferenceReceiver();
conferenceManager.getConferenceReceiver();
conferenceManager.getConferenceReceiver().addMember(this); conferenceManager.getConferenceReceiver().addMember(this);
} //}
/* /*
* For input treatments, the treatment manager does the resampling. * For input treatments, the treatment manager does the resampling.
...@@ -889,7 +887,7 @@ public class MemberReceiver implements MixDataSource, TreatmentDoneListener { ...@@ -889,7 +887,7 @@ public class MemberReceiver implements MixDataSource, TreatmentDoneListener {
* Only do this for sip calls. For some reason, other calls * Only do this for sip calls. For some reason, other calls
* are getting timed out if this "if" is removed. * are getting timed out if this "if" is removed.
*/ */
if (cp.isDistributedBridge() == true || phoneNumber.indexOf("sip:") < 0) { if (cp.isDistributedBridge() == true || phoneNumber.indexOf("sip:") < 0 || phoneNumber.indexOf("tel:") < 0) {
return false; return false;
} }
......
...@@ -142,7 +142,7 @@ public class OutgoingCallHandler extends CallHandler implements CallEventListene ...@@ -142,7 +142,7 @@ public class OutgoingCallHandler extends CallHandler implements CallEventListene
placeCall(); // no gateway involved, direct SIP call placeCall(); // no gateway involved, direct SIP call
} else if (cp.getProtocol() != null && ("WebRtc".equals(cp.getProtocol()) || "Rtmfp".equals(cp.getProtocol()))) { } else if (cp.getProtocol() != null && ("Videobridge".equals(cp.getProtocol()) || "WebRtc".equals(cp.getProtocol()) || "Rtmfp".equals(cp.getProtocol()))) {
placeCall(); // WebRtc call placeCall(); // WebRtc call
...@@ -172,6 +172,8 @@ public class OutgoingCallHandler extends CallHandler implements CallEventListene ...@@ -172,6 +172,8 @@ public class OutgoingCallHandler extends CallHandler implements CallEventListene
csa = new NSOutgoingCallAgent(this); csa = new NSOutgoingCallAgent(this);
} else if (protocol.equalsIgnoreCase("WebRtc")) { } else if (protocol.equalsIgnoreCase("WebRtc")) {
csa = new WebRtcCallAgent(this); csa = new WebRtcCallAgent(this);
} else if (protocol.equalsIgnoreCase("Videobridge")) {
csa = new VideobridgeCallAgent(this);
} else if (protocol.equalsIgnoreCase("Rtmfp")) { } else if (protocol.equalsIgnoreCase("Rtmfp")) {
csa = new RtmfpCallAgent(this); csa = new RtmfpCallAgent(this);
} else { } else {
......
/*
* Copyright 2007 Sun Microsystems, Inc.
*
* This file is part of jVoiceBridge.
*
* jVoiceBridge is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation and distributed hereunder
* to you.
*
* jVoiceBridge 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* Sun designates this particular file as subject to the "Classpath"
* exception as provided by Sun in the License file that accompanied this
* code.
*/
package com.sun.voip.server;
import org.jivesoftware.openfire.XMPPServer;
import com.sun.voip.CallParticipant;
import com.sun.voip.CallState;
import com.sun.voip.Logger;
import com.sun.voip.MediaInfo;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.util.*;
import org.dom4j.*;
import org.xmpp.packet.*;
import org.ifsoft.rayo.*;
public class VideobridgeCallAgent extends CallSetupAgent
{
private CallParticipant cp;
private MemberReceiver memberReceiver;
private MemberSender memberSender;
private MediaInfo mixerMediaPreference;
private static int startRTPPort = 0;
private static int stopRTPPort = 0;
private static Integer nextRTPPort = 0;
public VideobridgeCallAgent(CallHandler callHandler)
{
super(callHandler);
cp = callHandler.getCallParticipant();
mixerMediaPreference = callHandler.getConferenceManager().getMediaInfo();
memberSender = callHandler.getMemberSender();
memberReceiver = callHandler.getMemberReceiver();
String s = System.getProperty("com.sun.voip.server.FIRST_VIDEOBRIDGE_RTP_PORT");
try {
startRTPPort = Integer.parseInt(s);
} catch (NumberFormatException e) {
startRTPPort = 60000;
}
s = System.getProperty("com.sun.voip.server.LAST_VIDEOBRIDGE_RTP_PORT");
try {
stopRTPPort = Integer.parseInt(s);
} catch (NumberFormatException e) {
stopRTPPort = 70000;
}
nextRTPPort = startRTPPort;
}
public void initiateCall() throws IOException
{
String domainName = XMPPServer.getInstance().getServerInfo().getXMPPDomain();
try {
InetSocketAddress isaLocal = callHandler.getReceiveAddress();
int localRTPPort = isaLocal.getPort();
int localRTCPPort = localRTPPort + 1;
int remoteRTPPort = nextRTPPort;
int remoteRTCPPort = remoteRTPPort + 1;
synchronized (nextRTPPort)
{
nextRTPPort++;
if (nextRTPPort > stopRTPPort) nextRTPPort = startRTPPort;
}
setState(CallState.INVITED);
IQ iq = new IQ(IQ.Type.set);
iq.setFrom(cp.getCallOwner());
iq.setTo(domainName);
String id = "rayo-" + System.currentTimeMillis();
Element colibri = iq.setChildElement("colibri", "urn:xmpp:rayo:colibri:1");
colibri.addAttribute("videobridge", cp.getConferenceId());
colibri.addAttribute("localrtpport",String.valueOf(remoteRTPPort));
colibri.addAttribute("localrtcpport",String.valueOf(remoteRTCPPort));
colibri.addAttribute("remotertpport",String.valueOf(localRTPPort));
colibri.addAttribute("remotertcpport",String.valueOf(localRTCPPort));
colibri.addAttribute("codec", cp.getMediaPreference().equals("PCM/48000/2") ? "opus" : "pcmu");
RayoPlugin.component.sendPacket(iq);
setState(CallState.ANSWERED);
InetSocketAddress isaRemote = new InetSocketAddress("localhost", remoteRTPPort);
setEndpointAddress(isaRemote, (byte) (cp.getMediaPreference().equals("PCM/48000/2") ? 111 : 0), (byte)0, (byte)0);
setState(CallState.ESTABLISHED);
} catch (Exception e) {
Logger.println("Call " + cp + ": VideobridgeCallAgent: initiateCall exception ");
e.printStackTrace();
}
}
public String getSdp()
{
return null;
}
public void setRemoteMediaInfo(String sdp)
{
return;
}
}
...@@ -1026,15 +1026,34 @@ public class RayoComponent extends AbstractComponent ...@@ -1026,15 +1026,34 @@ public class RayoComponent extends AbstractComponent
try { try {
ConferenceManager conferenceManager = ConferenceManager.findConferenceManager(mixer); ConferenceManager conferenceManager = ConferenceManager.findConferenceManager(mixer);
if (conferenceManager.getMemberList().size() == 1) if (CallHandler.findCall("colibri-" + mixer) == null) // other participant than colibri
{
attachVideobridge(mixer, iq.getFrom(), conferenceManager.getMediaInfo().toString());
if (conferenceManager.getMemberList().size() == 1) // handset already in call
{ {
String recording = mixer + "-" + System.currentTimeMillis() + ".au"; String recording = mixer + "-" + System.currentTimeMillis() + ".au";
conferenceManager.recordConference(true, recording, "au"); conferenceManager.recordConference(true, recording, "au");
sendMucMessage(mixer, recording, iq.getFrom(), "Started voice recording"); sendMucMessage(mixer, recording, iq.getFrom(), "Started voice recording");
} }
}
sendMucMessage(mixer, null, iq.getFrom(), "Joined voice conversation"); sendMucMessage(mixer, null, iq.getFrom(), "Joined voice conversation");
} catch (ParseException pe) { // colibri joining as first participant
try {
ConferenceManager conferenceManager = ConferenceManager.getConference(mixer, "PCM/48000/2", mixer, false);
String recording = mixer + "-" + System.currentTimeMillis() + ".au";
conferenceManager.recordConference(true, recording, "au");
sendMucMessage(mixer, recording, iq.getFrom(), "Started voice recording");
attachVideobridge(mixer, iq.getFrom(), "PCM/48000/2");
} catch (Exception e) {
reply.setError(PacketError.Condition.item_not_found);
}
} catch (Exception e) { } catch (Exception e) {
reply.setError(PacketError.Condition.item_not_found); reply.setError(PacketError.Condition.item_not_found);
} }
...@@ -1069,6 +1088,7 @@ public class RayoComponent extends AbstractComponent ...@@ -1069,6 +1088,7 @@ public class RayoComponent extends AbstractComponent
{ {
conferenceManager.recordConference(false, null, null); conferenceManager.recordConference(false, null, null);
sendMucMessage(mixer, null, iq.getFrom(), "Stopped voice recording"); sendMucMessage(mixer, null, iq.getFrom(), "Stopped voice recording");
detachVideobridge(mixer);
} }
sendMucMessage(mixer, null, iq.getFrom(), "Left voice conversation"); sendMucMessage(mixer, null, iq.getFrom(), "Left voice conversation");
...@@ -1084,12 +1104,15 @@ public class RayoComponent extends AbstractComponent ...@@ -1084,12 +1104,15 @@ public class RayoComponent extends AbstractComponent
return reply; return reply;
} }
private void attachVideobridge(String conferenceId, JID participant, String mediaPreference)
private void sendMucMessage(String mixer, String recording, JID participant, String message)
{ {
if (XMPPServer.getInstance().getMultiUserChatManager().getMultiUserChatService("conference").hasChatRoom(mixer)) { //if (XMPPServer.getInstance().getPluginManager().getPlugin("jitsivideobridge") != null)
//{
Log.info("attachVideobridge Found Jitsi Videobridge, attaching.." + conferenceId);
MUCRoom room = XMPPServer.getInstance().getMultiUserChatManager().getMultiUserChatService("conference").getChatRoom(mixer); if (XMPPServer.getInstance().getMultiUserChatManager().getMultiUserChatService("conference").hasChatRoom(conferenceId)) {
MUCRoom room = XMPPServer.getInstance().getMultiUserChatManager().getMultiUserChatService("conference").getChatRoom(conferenceId);
if (room != null) if (room != null)
{ {
...@@ -1097,12 +1120,61 @@ public class RayoComponent extends AbstractComponent ...@@ -1097,12 +1120,61 @@ public class RayoComponent extends AbstractComponent
{ {
if (participant.toBareJID().equals(role.getUserAddress().toBareJID())) if (participant.toBareJID().equals(role.getUserAddress().toBareJID()))
{ {
sendMessage(new JID(mixer + "@conference." + getDomain()), participant, message, recording, "groupchat"); Log.info("attachVideobridge Found participant " + participant.toBareJID());
try {
CallParticipant vp = new CallParticipant();
vp.setCallId("colibri-" + conferenceId);
vp.setCallOwner(participant.toString());
vp.setProtocol("Videobridge");
vp.setPhoneNumber(participant.getNode());
vp.setMediaPreference(mediaPreference);
vp.setConferenceId(conferenceId);
OutgoingCallHandler videoBridgeHandler = new OutgoingCallHandler(null, vp);
videoBridgeHandler.start();
} catch (Exception e) {
e.printStackTrace();
}
break; break;
} }
} }
} }
} }
//}
}
private void detachVideobridge(String conferenceId)
{
try {
Log.info("Jitsi Videobridge, detaching.." + conferenceId);
CallHandler callHandler = CallHandler.findCall("colibri-" + conferenceId);
if (callHandler != null)
{
CallHandler.hangup("colibri-" + conferenceId, "Detaching from Jitsi Videobridge");
}
} catch (Exception e) {
e.printStackTrace();
}
}
private void sendMucMessage(String mixer, String recording, JID participant, String message)
{
if (XMPPServer.getInstance().getMultiUserChatManager().getMultiUserChatService("conference").hasChatRoom(mixer)) {
MUCRoom room = XMPPServer.getInstance().getMultiUserChatManager().getMultiUserChatService("conference").getChatRoom(mixer);
if (room != null)
{
sendMessage(new JID(mixer + "@conference." + getDomain()), participant, message, recording, "groupchat");
}
}
} }
private IQ handleDialCommand(DialCommand command, IQ iq, boolean transferCall) private IQ handleDialCommand(DialCommand command, IQ iq, boolean transferCall)
......
...@@ -76,7 +76,7 @@ public class RayoPlugin implements Plugin, SessionEventListener { ...@@ -76,7 +76,7 @@ public class RayoPlugin implements Plugin, SessionEventListener {
private boolean hasPublicIP = false; private boolean hasPublicIP = false;
private Application bridge = new Application(); private Application bridge = new Application();
private RayoComponent component = null; public static RayoComponent component = null;
public RayoPlugin() { public RayoPlugin() {
final String os = System.getProperty("os.name"); final String os = System.getProperty("os.name");
......
...@@ -41,7 +41,9 @@ public class Application implements CallEventListener { ...@@ -41,7 +41,9 @@ public class Application implements CallEventListener {
System.setProperty("com.sun.voip.server.LOGLEVEL", "99"); System.setProperty("com.sun.voip.server.LOGLEVEL", "99");
System.setProperty("com.sun.voip.server.FIRST_RTP_PORT", "3200"); System.setProperty("com.sun.voip.server.FIRST_RTP_PORT", "3200");
System.setProperty("com.sun.voip.server.LAST_RTP_PORT", "3299"); System.setProperty("com.sun.voip.server.LAST_RTP_PORT", "3899");
System.setProperty("com.sun.voip.server.FIRST_VIDEOBRIDGE_RTP_PORT", "3900");
System.setProperty("com.sun.voip.server.LAST_VIDEOBRIDGE_RTP_PORT", "3999");
System.setProperty("com.sun.voip.server.Bridge.logDirectory", logDir); System.setProperty("com.sun.voip.server.Bridge.logDirectory", logDir);
System.setProperty("com.sun.voip.server.BRIDGE_LOG", "bridge.log"); System.setProperty("com.sun.voip.server.BRIDGE_LOG", "bridge.log");
System.setProperty("com.sun.voip.server.LOGLEVEL", "99"); System.setProperty("com.sun.voip.server.LOGLEVEL", "99");
......
...@@ -375,6 +375,41 @@ Strophe.addConnectionPlugin('rayo', ...@@ -375,6 +375,41 @@ Strophe.addConnectionPlugin('rayo',
this._offhook(mixer, headers, function() this._offhook(mixer, headers, function()
{ {
that._dial(mixer, from, to, headers);
});
},
voicebridge: function(mixer, from, to, headers)
{
console.log('Rayo plugin voicebridge ' + mixer);
var that = this;
var iq = $iq({to: mixer + "@" + this._connection.domain, from: this._connection.jid, type: "get"}).c("join", {xmlns: Strophe.NS.RAYO_CORE, "mixer-name": mixer});
//console.log(iq.toString());
this._connection.sendIQ(iq, function(response)
{
that._dial(mixer, from, to, headers);
}, function(error) {
$('error', error).each(function()
{
var errorcode = $(this).attr('code');
if (that.callbacks && that.callbacks.onError) that.callbacks.onError("voicebridge failure " + errorcode);
});
});
},
_dial: function(mixer, from, to, headers)
{
//console.log('Rayo plugin _dial ' + from + " " + to);
//console.log(headers)
var that = this;
var iq = $iq({to: that._connection.domain, from: that._connection.jid, type: "get"}).c("dial", {xmlns: Strophe.NS.RAYO_CORE, to: to, from: from}); var iq = $iq({to: that._connection.domain, from: that._connection.jid, type: "get"}).c("dial", {xmlns: Strophe.NS.RAYO_CORE, to: to, from: from});
if (headers) if (headers)
...@@ -434,10 +469,8 @@ Strophe.addConnectionPlugin('rayo', ...@@ -434,10 +469,8 @@ Strophe.addConnectionPlugin('rayo',
that._onhook(); that._onhook();
}); });
});
}, },
_isOffhook: function() _isOffhook: function()
{ {
return this.localStream != null; return this.localStream != null;
......
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