Commit 459e9c95 authored by Dele Olajide's avatar Dele Olajide Committed by dele

Rayo Plugin - Implemented Mute/Unmute

git-svn-id: http://svn.igniterealtime.org/svn/repos/openfire/trunk@13780 b35dd754-fafc-0310-a699-88a17e54d16e
parent 9674c91d
......@@ -94,8 +94,22 @@ body {
-ms-filter: progid:DXImageTransform.Microsoft.Shadow(Color=rgba(0, 0, 0, 0.2),Direction=135,Strength=5); }
#callStatus.busy .callerName:before {
content: "Busy: "; }
#callStatus.muted {
background-color: #bbbb00;
background-image: rgba(255, 255, 255, 0.3);
background-image: -moz-linear-gradient(top, rgba(255, 255, 255, 0.3), rgba(50, 50, 50, 0.1));
background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0, rgba(255, 255, 255, 0.3)), color-stop(1, rgba(50, 50, 50, 0.1)));
-ms-filter: progid:DXImageTransform.Microsoft.gradient(startColorStr='$top', EndColorStr='$bottom');
border-top: 2px solid white;
border-bottom: 2px solid #bbbbbb;
-webkit-box-shadow: rgba(0, 0, 0, 0.2) 0 3px 5px;
-moz-box-shadow: rgba(0, 0, 0, 0.2) 0 3px 5px;
box-shadow: rgba(0, 0, 0, 0.2) 0 3px 5px;
-ms-filter: progid:DXImageTransform.Microsoft.Shadow(Color=rgba(0, 0, 0, 0.2),Direction=135,Strength=5); }
#callStatus.muted .callerName:before {
content: "Muted: "; }
#callStatus.held {
background-color: #ff7474;
background-color: #ff3434;
background-image: rgba(255, 255, 255, 0.3);
background-image: -moz-linear-gradient(top, rgba(255, 255, 255, 0.3), rgba(50, 50, 50, 0.1));
background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0, rgba(255, 255, 255, 0.3)), color-stop(1, rgba(50, 50, 50, 0.1)));
......
......@@ -60,6 +60,10 @@
{
cls: 'hold',
label: 'Hold Call'
},
{
cls: 'mute',
label: 'Mute Call'
}],
timer: true
},
......@@ -69,6 +73,12 @@
label: 'Join Call'
}],
},
muted: {
buttons: [{
cls: 'unmute',
label: 'Unmute Call'
}],
},
held: {
buttons: [{
cls: 'join',
......@@ -236,6 +246,11 @@
self.call.answer();
}
};
self.ignore = function () {
if (self.call) {
self.call.hangup();
}
};
self.join = function () {
if (self.call) {
self.call.join();
......@@ -251,6 +266,16 @@
self.call.leave();
}
};
self.mute = function () {
if (self.call) {
self.call.mute(true);
}
};
self.unmute = function () {
if (self.call) {
self.call.mute(false);
}
};
self.cancel = function () {
if (self.call) {
self.call.hangup();
......
......@@ -59,6 +59,9 @@
} else if (window.dialer.getCallLabel() == "Unhold") {
window.candybar.call.join();
} else if (window.dialer.getCallLabel() == "Unmute") {
window.candybar.call.mute(false);
} else {
console.error('bad call state');
}
......@@ -248,6 +251,20 @@
//console.log('onUnjoin ' + jid + " " + mixer + " " + callId);
},
onMute: function(callId) {
//console.log('onMute ' + callId);
window.candybar.setState('muted');
window.dialer.setCallLabel('Unmute');
},
offMute: function(callId) {
//console.log('offMute ' + callId);
window.candybar.setState('active');
window.dialer.setCallLabel('Hangup');
},
onError: function(e) {
console.error(e);
......
......@@ -109,6 +109,24 @@ Strophe.addConnectionPlugin('rayo',
this._onhook();
},
mute: function(callId, flag)
{
//console.log('Rayo plugin mute ' + callId + " " + flag);
var that = this;
var iq = $iq({to: callId + "@rayo." + this._connection.domain, from: this._connection.jid, type: "get"}).c( flag ? "mute" : "unmute", {xmlns: Strophe.NS.RAYO_CORE});
that._connection.sendIQ(iq, null, function(error)
{
$('error', error).each(function()
{
var errorcode = $(this).attr('code');
if (that.callbacks && that.callbacks.onError) that.callbacks.onError("mute/unmute failure " + errorcode);
});
});
},
answer: function(callId, mixer, headers)
{
//console.log('Rayo plugin accept ' + callId + " " + mixer);
......@@ -193,6 +211,7 @@ Strophe.addConnectionPlugin('rayo',
hangup: function() {that.hangup(callId);},
join: function() {that.join(mixer, headers);},
leave: function() {that.leave(mixer);},
mute: function(flag) {that.mute(callId, flag);},
from: from,
to: to,
......@@ -426,6 +445,7 @@ Strophe.addConnectionPlugin('rayo',
answer: function() {that.answer(callId, mixer, headers);},
join: function() {that.join(mixer, headers);},
leave: function() {that.leave(mixer);},
mute: function(flag) {that.mute(callId, flag);},
from: callFrom,
to: callTo,
......@@ -530,6 +550,28 @@ Strophe.addConnectionPlugin('rayo',
}
});
$(presence).find('onmute').each(function()
{
//console.log(presence);
if ($(this).attr('xmlns') == Strophe.NS.RAYO_CORE)
{
var callId = Strophe.getNodeFromJid(from);
if (that.callbacks && that.callbacks.onMute) that.callbacks.onMute(callId);
}
});
$(presence).find('offmute').each(function()
{
//console.log(presence);
if ($(this).attr('xmlns') == Strophe.NS.RAYO_CORE)
{
var callId = Strophe.getNodeFromJid(from);
if (that.callbacks && that.callbacks.offMute) that.callbacks.offMute(callId);
}
});
$(presence).find('ringing').each(function()
{
if ($(this).attr('xmlns') == Strophe.NS.RAYO_CORE)
......@@ -573,6 +615,7 @@ Strophe.addConnectionPlugin('rayo',
answer: function() {that.answer(callId, mixer, headers);},
join: function() {that.join(mixer, headers);},
leave: function() {that.leave(mixer);},
mute: function(flag) {that.mute(callId, flag);},
id: callId,
from: Strophe.getNodeFromJid(jid)
......
package com.rayo.core.verb;
public class MutedEvent extends AbstractVerbEvent {
public MutedEvent() {}
public MutedEvent(Verb verb) {
super(verb);
}
}
package com.rayo.core.verb;
public class UnmutedEvent extends AbstractVerbEvent {
public UnmutedEvent() {}
public UnmutedEvent(Verb verb) {
super(verb);
}
}
......@@ -19,14 +19,19 @@ package org.ifsoft.rayo;
import org.dom4j.*;
import org.jivesoftware.openfire.container.Plugin;
import org.jivesoftware.openfire.container.PluginManager;
import org.jivesoftware.openfire.SessionManager;
import org.jivesoftware.openfire.session.ClientSession;
import org.jivesoftware.util.JiveGlobals;
import org.jivesoftware.openfire.muc.*;
import org.jivesoftware.openfire.muc.spi.*;
import org.jivesoftware.openfire.XMPPServer;
import org.jivesoftware.openfire.group.Group;
import org.jivesoftware.openfire.group.GroupManager;
import org.jivesoftware.openfire.group.GroupNotFoundException;
import org.jivesoftware.util.JiveGlobals;
import org.xmpp.packet.JID;
import org.slf4j.Logger;
......@@ -54,7 +59,6 @@ import org.voicebridge.*;
public class RayoComponent extends AbstractComponent
implements TreatmentDoneListener,
CallEventListener,
......@@ -89,6 +93,13 @@ public class RayoComponent extends AbstractComponent
handsetProvider = new HandsetProvider();
handsetProvider.setValidator(new Validator());
Plugin fastpath = XMPPServer.getInstance().getPluginManager().getPlugin("fastpath");
if (fastpath != null)
{
Log.info("RayoComponent found Fastpath");
}
}
public String getName() {
......@@ -158,12 +169,16 @@ public class RayoComponent extends AbstractComponent
if (object instanceof ConnectCommand) {
} else if (object instanceof HoldCommand) {
// implemented as onhook on client
} else if (object instanceof UnholdCommand) {
// implemented as offhook on client
} else if (object instanceof MuteCommand) {
reply = handleMuteCommand((MuteCommand) object, iq);
} else if (object instanceof UnmuteCommand) {
reply = handleMuteCommand((UnmuteCommand) object, iq);
} else if (object instanceof JoinCommand) {
reply = handleJoinCommand((JoinCommand) object, iq);
......@@ -181,6 +196,7 @@ public class RayoComponent extends AbstractComponent
reply = handleHangupCommand(iq);
} else if (object instanceof RejectCommand) {
// implemented as hangup on client
} else if (object instanceof RedirectCommand) {
......@@ -210,6 +226,68 @@ public class RayoComponent extends AbstractComponent
}
private IQ handleMuteCommand(Object object, IQ iq)
{
Log.info("RayoComponent handleMuteCommand");
boolean muted = object instanceof MuteCommand;
IQ reply = IQ.createResultIQ(iq);
String callId = JID.escapeNode(iq.getFrom().toString());
CallHandler handler = CallHandler.findCall(callId);
if (handler != null)
{
handler.setMuted(muted);
try {
ConferenceManager conferenceManager = ConferenceManager.findConferenceManager(handler.getCallParticipant().getConferenceId());
ArrayList memberList = conferenceManager.getMemberList();
synchronized (memberList)
{
for (int i = 0; i < memberList.size(); i++)
{
ConferenceMember member = (ConferenceMember) memberList.get(i);
CallHandler callHandler = member.getCallHandler();
CallParticipant cp = callHandler.getCallParticipant();
String target = cp.getCallOwner();
Log.info( "RayoComponent handleMuteCommand route event to " + target);
if (target != null)
{
Presence presence = new Presence();
presence.setFrom(callId + "@rayo." + getDomain());
presence.setTo(target);
if (muted)
{
MutedEvent event = new MutedEvent();
presence.getElement().add(toXML(event));
} else {
UnmutedEvent event = new UnmutedEvent();
presence.getElement().add(toXML(event));
}
sendPacket(presence);
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
} else {
reply.setError(PacketError.Condition.item_not_found);
}
return reply;
}
private IQ handleOnOffHookCommand(Object object, IQ iq)
{
Log.info("RayoComponent handleOnOffHookCommand");
......@@ -432,17 +510,12 @@ public class RayoComponent extends AbstractComponent
Map<String, String> headers = command.getHeaders();
headers.put("call_protocol", "XMPP");
try {
Presence presence = new Presence();
presence.setFrom(iq.getTo());
presence.setTo(callJID);
presence.getElement().add(rayoProvider.toXML(new RingingEvent(null, headers)));
sendPacket(presence);
} catch (Exception e) {
reply.setError(PacketError.Condition.item_not_found);
}
}
return reply;
......@@ -762,15 +835,32 @@ public class RayoComponent extends AbstractComponent
}
}
if (count == 0)
} catch (GroupNotFoundException e) {
if (XMPPServer.getInstance().getMultiUserChatManager().getMultiUserChatService("conference").hasChatRoom(destination.getNode())) {
MUCRoom room = XMPPServer.getInstance().getMultiUserChatManager().getMultiUserChatService("conference").getChatRoom(destination.getNode());
if (room != null)
{
for (MUCRole role : room.getOccupants())
{
if (iq.getFrom().toBareJID().equals(role.getUserAddress().toBareJID()) == false)
{
routeXMPPCall(reply, role.getUserAddress(), source, calledName, headers);
count++;
}
}
}
} else {
reply.setError(PacketError.Condition.item_not_found);
return reply;
}
}
} catch (GroupNotFoundException e) {
if (count == 0)
{
reply.setError(PacketError.Condition.item_not_found);
return reply;
}
}
......@@ -1312,6 +1402,8 @@ public class RayoComponent extends AbstractComponent
{
Log.info( "RayoComponent routeJoinEvent " + callee + " " + callId + " " + groupName + " " + memberCount + " " + farParty);
if (callee == null) return;
Presence presence = new Presence();
presence.setFrom(callId + "@rayo." + getDomain());
presence.setTo(callee);
......@@ -1437,13 +1529,17 @@ public class RayoComponent extends AbstractComponent
String callId = "rayo-incoming-" + System.currentTimeMillis();
cp.setCallId(callId);
cp.setMediaPreference("PCMU/8000/1");
cp.setConferenceId(callId);
cp.setConferenceDisplayName(cp.getToPhoneNumber());
ConferenceManager.setCallId(callId, callId);
ConferenceManager conferenceManager = ConferenceManager.getConference(callId, cp.getMediaPreference(), cp.getToPhoneNumber(), false);
conferenceManager.setCallId(callId);
Map<String, String> headers = cp.getHeaders();
headers.put("mixer_name", callId);
headers.put("call_protocol", "SIP");
headers.put("group_name", cp.getToPhoneNumber());
if (foundUser != null) // send this call to specific user
{
......@@ -1451,10 +1547,9 @@ public class RayoComponent extends AbstractComponent
routeSIPCall(foundUser, cp, callId, headers);
return true;
}
// send to members of group
try {
Group group = GroupManager.getInstance().getGroup(cp.getToPhoneNumber());
headers.put("group_name", cp.getToPhoneNumber());
for (JID memberJID : group.getMembers())
{
......@@ -1470,9 +1565,25 @@ public class RayoComponent extends AbstractComponent
} catch (GroupNotFoundException e) {
// Group not found
if (XMPPServer.getInstance().getMultiUserChatManager().getMultiUserChatService("conference").hasChatRoom(cp.getToPhoneNumber())) {
MUCRoom room = XMPPServer.getInstance().getMultiUserChatManager().getMultiUserChatService("conference").getChatRoom(cp.getToPhoneNumber());
if (room != null)
{
for (MUCRole role : room.getOccupants())
{
routeSIPCall(role.getUserAddress(), cp, callId, headers);
}
}
return true;
} else {
return false;
}
}
}
public void routeSIPCall(JID callee, CallParticipant cp, String callId, Map<String, String> headers)
{
......@@ -1522,6 +1633,12 @@ public class RayoComponent extends AbstractComponent
} else if (object instanceof OffHoldEvent) {
createOffHoldEvent((OffHoldEvent) object, document);
} else if (object instanceof MutedEvent) {
createMutedEvent((MutedEvent) object, document);
} else if (object instanceof UnmutedEvent) {
createUnmutedEvent((UnmutedEvent) object, document);
}
}
......@@ -1536,4 +1653,16 @@ public class RayoComponent extends AbstractComponent
Element root = document.addElement(new QName("offhold", new Namespace("", "urn:xmpp:rayo:1")));
return document;
}
private Document createMutedEvent(MutedEvent muted, Document document)
{
Element root = document.addElement(new QName("onmute", new Namespace("", "urn:xmpp:rayo:1")));
return document;
}
private Document createUnmutedEvent(UnmutedEvent unmuted, Document document)
{
Element root = document.addElement(new QName("offmute", new Namespace("", "urn:xmpp:rayo:1")));
return document;
}
}
......@@ -109,6 +109,24 @@ Strophe.addConnectionPlugin('rayo',
this._onhook();
},
mute: function(callId, flag)
{
//console.log('Rayo plugin mute ' + callId + " " + flag);
var that = this;
var iq = $iq({to: callId + "@rayo." + this._connection.domain, from: this._connection.jid, type: "get"}).c( flag ? "mute" : "unmute", {xmlns: Strophe.NS.RAYO_CORE});
that._connection.sendIQ(iq, null, function(error)
{
$('error', error).each(function()
{
var errorcode = $(this).attr('code');
if (that.callbacks && that.callbacks.onError) that.callbacks.onError("mute/unmute failure " + errorcode);
});
});
},
answer: function(callId, mixer, headers)
{
//console.log('Rayo plugin accept ' + callId + " " + mixer);
......@@ -193,6 +211,7 @@ Strophe.addConnectionPlugin('rayo',
hangup: function() {that.hangup(callId);},
join: function() {that.join(mixer, headers);},
leave: function() {that.leave(mixer);},
mute: function(flag) {that.mute(callId, flag);},
from: from,
to: to,
......@@ -426,6 +445,7 @@ Strophe.addConnectionPlugin('rayo',
answer: function() {that.answer(callId, mixer, headers);},
join: function() {that.join(mixer, headers);},
leave: function() {that.leave(mixer);},
mute: function(flag) {that.mute(callId, flag);},
from: callFrom,
to: callTo,
......@@ -530,6 +550,28 @@ Strophe.addConnectionPlugin('rayo',
}
});
$(presence).find('onmute').each(function()
{
//console.log(presence);
if ($(this).attr('xmlns') == Strophe.NS.RAYO_CORE)
{
var callId = Strophe.getNodeFromJid(from);
if (that.callbacks && that.callbacks.onMute) that.callbacks.onMute(callId);
}
});
$(presence).find('offmute').each(function()
{
//console.log(presence);
if ($(this).attr('xmlns') == Strophe.NS.RAYO_CORE)
{
var callId = Strophe.getNodeFromJid(from);
if (that.callbacks && that.callbacks.offMute) that.callbacks.offMute(callId);
}
});
$(presence).find('ringing').each(function()
{
if ($(this).attr('xmlns') == Strophe.NS.RAYO_CORE)
......@@ -573,6 +615,7 @@ Strophe.addConnectionPlugin('rayo',
answer: function() {that.answer(callId, mixer, headers);},
join: function() {that.join(mixer, headers);},
leave: function() {that.leave(mixer);},
mute: function(flag) {that.mute(callId, flag);},
id: callId,
from: Strophe.getNodeFromJid(jid)
......
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