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

Rayo plugin - Implementing Rayo IQHandlers

git-svn-id: http://svn.igniterealtime.org/svn/repos/openfire/trunk@13785 b35dd754-fafc-0310-a699-88a17e54d16e
parent d989eac3
...@@ -60,10 +60,18 @@ ...@@ -60,10 +60,18 @@
{ {
cls: 'hold', cls: 'hold',
label: 'Hold Call' label: 'Hold Call'
}, },
{ {
cls: 'mute', cls: 'mute',
label: 'Mute Call' label: 'Mute Call'
},
{
cls: 'redirect',
label: 'Redirect Call'
},
{
cls: 'private',
label: 'Private Call'
}], }],
timer: true timer: true
}, },
...@@ -263,14 +271,24 @@ ...@@ -263,14 +271,24 @@
}; };
self.hold = function () { self.hold = function () {
if (self.call) { if (self.call) {
self.call.leave(); self.call.hold();
}
};
self.redirect = function () {
if (self.call) {
self.call.redirect(prompt("Please enter new destination:","sip:xxxx@domain.com"));
} }
}; };
self.mute = function () { self.mute = function () {
if (self.call) { if (self.call) {
self.call.mute(true); self.call.mute(true);
} }
}; };
self.private = function () {
if (self.call) {
self.call.private();
}
};
self.unmute = function () { self.unmute = function () {
if (self.call) { if (self.call) {
self.call.mute(false); self.call.mute(false);
......
...@@ -38,6 +38,11 @@ ...@@ -38,6 +38,11 @@
onHide: function () { onHide: function () {
//console.log('removed it'); //console.log('removed it');
}, },
onHangup: function (number) {
window.candybar.call.hangup();
},
onCall: function (number) { onCall: function (number) {
if (window.dialer.getCallLabel() == "Call") { if (window.dialer.getCallLabel() == "Call") {
...@@ -62,6 +67,12 @@ ...@@ -62,6 +67,12 @@
} else if (window.dialer.getCallLabel() == "Unmute") { } else if (window.dialer.getCallLabel() == "Unmute") {
window.candybar.call.mute(false); window.candybar.call.mute(false);
} else if (window.dialer.getCallLabel() == "Private") {
window.candybar.call.private();
} else if (window.dialer.getCallLabel() == "Public") {
window.candybar.call.private();
} else { } else {
console.error('bad call state'); console.error('bad call state');
} }
...@@ -259,12 +270,36 @@ ...@@ -259,12 +270,36 @@
}, },
offMute: function(callId) { offMute: function(callId) {
//console.log('offMute ' + callId); console.log('offMute ' + callId);
window.candybar.setState('active'); window.candybar.setState('active');
window.dialer.setCallLabel('Hangup'); window.dialer.setCallLabel('Hangup');
}, },
onPrivate: function(callId) {
//console.log('onPrivate ' + callId);
window.candybar.call.privateCall = true;
window.dialer.setCallLabel('Public');
},
offPrivate: function(callId) {
//console.log('offPrivate ' + callId);
window.candybar.call.privateCall = false;
window.dialer.setCallLabel('Hangup');
},
onRedirect: function(callId) {
//console.log('onRedirect ' + callId);
window.candybar.endGently();
window.candybar.call = null;
window.dialer.setCallLabel('Call');
stopTone();
},
onError: function(e) { onError: function(e) {
console.error(e); console.error(e);
......
...@@ -54,13 +54,13 @@ Strophe.addConnectionPlugin('rayo', ...@@ -54,13 +54,13 @@ Strophe.addConnectionPlugin('rayo',
//console.log("hangup " + callId); //console.log("hangup " + callId);
var that = this; var that = this;
var iq = $iq({to: callId + "@rayo." + this._connection.domain, from: this._connection.jid, type: "get"}).c("hangup", {xmlns: Strophe.NS.RAYO_CORE}); var iq = $iq({to: callId + "@" + this._connection.domain, from: this._connection.jid, type: "get"}).c("hangup", {xmlns: Strophe.NS.RAYO_CORE});
//console.log(iq.toString()); //console.log(iq.toString());
that._connection.sendIQ(iq, function() that._connection.sendIQ(iq, function()
{ {
this._onhook(); that._onhook();
}, function(error) { }, function(error) {
...@@ -108,13 +108,98 @@ Strophe.addConnectionPlugin('rayo', ...@@ -108,13 +108,98 @@ Strophe.addConnectionPlugin('rayo',
this._onhook(); this._onhook();
}, },
hold: function(callId)
{
//console.log("hold " + callId);
var that = this;
var iq = $iq({to: callId + "@rayo." + this._connection.domain, from: this._connection.jid, type: "get"}).c("hold", {xmlns: Strophe.NS.RAYO_HANDSET});
//console.log(iq.toString());
that._connection.sendIQ(iq, function()
{
that._onhook();
}, function(error) {
//console.log(error);
$('error', error).each(function()
{
var errorcode = $(this).attr('code');
if (that.callbacks && that.callbacks.onError) that.callbacks.onError("hold failure " + errorcode);
});
});
},
redirect: function(to, mixer, headers)
{
//console.log("redirect " + to + " " + mixer);
var that = this;
var iq = $iq({to: callId + "@rayo." + this._connection.domain, from: this._connection.jid, type: "get"}).c("redirect", {xmlns: Strophe.NS.RAYO_CORE, to: to});
if (headers)
{
var hdrs = Object.getOwnPropertyNames(headers)
for (var i=0; i< hdrs.length; i++)
{
var name = hdrs[i];
var value = headers[name];
if (value) iq.c("header", {name: name, value: value}).up();
}
}
console.log(iq.toString());
that._connection.sendIQ(iq, function(response)
{
$('ref', response).each(function()
{
callId = $(this).attr('id');
if (that._isOffhook()) that._onhook();
if (that.callbacks && that.callbacks.onRedirect) that.callbacks.onRedirect(callId);
});
}, function(error) {
console.log(error);
$('error', error).each(function()
{
var errorcode = $(this).attr('code');
if (that.callbacks && that.callbacks.onError) that.callbacks.onError("redirect failure " + errorcode);
});
});
},
private: function(callId, flag)
{
//console.log('Rayo plugin private ' + callId + " " + flag);
var that = this;
var iq = $iq({to: callId + "@rayo." + this._connection.domain, from: this._connection.jid, type: "get"}).c( flag ? "private" : "public", {xmlns: Strophe.NS.RAYO_HANDSET});
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("private/public failure " + errorcode);
});
});
},
mute: function(callId, flag) mute: function(callId, flag)
{ {
//console.log('Rayo plugin mute ' + callId + " " + flag); //console.log('Rayo plugin mute ' + callId + " " + flag);
var that = this; 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}); var iq = $iq({to: callId + "@rayo." + this._connection.domain, from: this._connection.jid, type: "get"}).c( flag ? "mute" : "unmute", {xmlns: Strophe.NS.RAYO_HANDSET});
that._connection.sendIQ(iq, null, function(error) that._connection.sendIQ(iq, null, function(error)
{ {
...@@ -127,32 +212,37 @@ Strophe.addConnectionPlugin('rayo', ...@@ -127,32 +212,37 @@ Strophe.addConnectionPlugin('rayo',
}, },
answer: function(callId, mixer, headers) answer: function(callId, mixer, headers, callFrom)
{ {
//console.log('Rayo plugin accept ' + callId + " " + mixer); //console.log('Rayo plugin accept ' + callId + " " + mixer);
//console.log(headers)
var that = this; var that = this;
if (this._isOffhook()) this._onhook(); if (this._isOffhook()) this._onhook();
if (!headers) headers = {};
headers.call_id = callId;
//console.log(headers)
this._offhook(mixer, headers, function() this._offhook(mixer, headers, function()
{ {
var iq = $iq({to: callId + "@rayo." + that._connection.domain, from: that._connection.jid, type: "get"}).c("answer", {xmlns: Strophe.NS.RAYO_CORE}); var iq = $iq({to: callId + "@rayo." + that._connection.domain, from: that._connection.jid, type: "get"}).c("answer", {xmlns: Strophe.NS.RAYO_CORE});
var hdrs = Object.getOwnPropertyNames(headers)
if (headers) for (var i=0; i< hdrs.length; i++)
{ {
var hdrs = Object.getOwnPropertyNames(headers) var name = hdrs[i];
var value = headers[name];
for (var i=0; i< hdrs.length; i++)
{
var name = hdrs[i];
var value = headers[name];
if (value) iq.c("header", {name: name, value: value}).up(); if (value) iq.c("header", {name: name, value: value}).up();
}
} }
iq.c("header", {name: "caller_id", value: callFrom}).up();
iq.c("header", {name: "mixer_name", value: mixer}).up();
//console.log(iq.toString()); //console.log(iq.toString());
that._connection.sendIQ(iq, null, function(error) that._connection.sendIQ(iq, null, function(error)
...@@ -176,11 +266,11 @@ Strophe.addConnectionPlugin('rayo', ...@@ -176,11 +266,11 @@ Strophe.addConnectionPlugin('rayo',
var mixer = "rayo-outgoing-" + Math.random().toString(36).substr(2,9); var mixer = "rayo-outgoing-" + Math.random().toString(36).substr(2,9);
if (this._isOffhook()) this._onhook(); if (this._isOffhook()) this._onhook();
this._offhook(mixer, headers, function() this._offhook(mixer, headers, function()
{ {
var iq = $iq({to: "rayo." + 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)
{ {
...@@ -207,15 +297,19 @@ Strophe.addConnectionPlugin('rayo', ...@@ -207,15 +297,19 @@ Strophe.addConnectionPlugin('rayo',
{ {
that.callbacks.onAccept( that.callbacks.onAccept(
{ {
digit: function(tone) {that.digit(callId, tone);}, digit: function(tone) {that.digit(callId, tone);},
hangup: function() {that.hangup(callId);}, redirect: function(to) {that.redirect(to, mixer, headers);},
join: function() {that.join(mixer, headers);}, hangup: function() {that.hangup(callId);},
leave: function() {that.leave(mixer);}, hold: function() {that.hold(callId);},
mute: function(flag) {that.mute(callId, flag);}, join: function() {that.join(mixer, headers);},
leave: function() {that.leave(mixer);},
mute: function(flag) {that.mute(callId, flag);},
private: function() {that.private(callId, !this.privateCall);},
from: from, from: from,
to: to, to: to,
id: callId id: callId,
privateCall: false
}); });
} }
}); });
...@@ -256,7 +350,7 @@ Strophe.addConnectionPlugin('rayo', ...@@ -256,7 +350,7 @@ Strophe.addConnectionPlugin('rayo',
var codec = (headers && headers.codec_name) ? headers.codec_name : (that.callbacks.codec_name ? that.callbacks.codec_name : "OPUS"); var codec = (headers && headers.codec_name) ? headers.codec_name : (that.callbacks.codec_name ? that.callbacks.codec_name : "OPUS");
var iq = $iq({to: "rayo." + that._connection.domain, from: that._connection.jid, type: "get"}).c("offhook", {xmlns: Strophe.NS.RAYO_HANDSET, sipuri: sipuri, mixer: mixer, group: group, codec: codec}); var iq = $iq({to: that._connection.domain, from: that._connection.jid, type: "get"}).c("offhook", {xmlns: Strophe.NS.RAYO_HANDSET, sipuri: sipuri, mixer: mixer, group: group, codec: codec});
//console.log(iq.toString()) //console.log(iq.toString())
...@@ -352,8 +446,9 @@ Strophe.addConnectionPlugin('rayo', ...@@ -352,8 +446,9 @@ Strophe.addConnectionPlugin('rayo',
var stereo = (headers && headers.stereo_pan) ? headers.stereo_pan : (that.callbacks.stereo_pan ? that.callbacks.stereo_pan : "0"); var stereo = (headers && headers.stereo_pan) ? headers.stereo_pan : (that.callbacks.stereo_pan ? that.callbacks.stereo_pan : "0");
var codec = (headers && headers.codec_name) ? headers.codec_name : (that.callbacks.codec_name ? that.callbacks.codec_name : "OPUS"); var codec = (headers && headers.codec_name) ? headers.codec_name : (that.callbacks.codec_name ? that.callbacks.codec_name : "OPUS");
var group = (headers && headers.group_name) ? headers.group_name : ""; var group = (headers && headers.group_name) ? headers.group_name : "";
var callid = (headers && headers.call_id) ? headers.call_id : "";
var iq = $iq({to: "rayo." + that._connection.domain, from: that._connection.jid, type: "get"}).c("offhook", {xmlns: Strophe.NS.RAYO_HANDSET, cryptoSuite: that.cryptoSuite, localCrypto: that.localCrypto, remoteCrypto: that.remoteCrypto, codec: codec, stereo: stereo, mixer: mixer, group: group}); var iq = $iq({to: that._connection.domain, from: that._connection.jid, type: "get"}).c("offhook", {xmlns: Strophe.NS.RAYO_HANDSET, cryptoSuite: that.cryptoSuite, localCrypto: that.localCrypto, remoteCrypto: that.remoteCrypto, codec: codec, stereo: stereo, mixer: mixer, group: group, callid: callid});
//console.log(iq.toString()) //console.log(iq.toString())
...@@ -384,7 +479,7 @@ Strophe.addConnectionPlugin('rayo', ...@@ -384,7 +479,7 @@ Strophe.addConnectionPlugin('rayo',
//console.log('Rayo plugin onhook ' + this.handsetId); //console.log('Rayo plugin onhook ' + this.handsetId);
that = this; that = this;
var server = this.handsetId + "@rayo." + this._connection.domain; var server = this.handsetId + "@" + this._connection.domain;
this._connection.sendIQ($iq({to: server, from: this._connection.jid, type: "get"}).c('onhook', {xmlns: Strophe.NS.RAYO_HANDSET}), function(response) this._connection.sendIQ($iq({to: server, from: this._connection.jid, type: "get"}).c('onhook', {xmlns: Strophe.NS.RAYO_HANDSET}), function(response)
{ {
...@@ -440,16 +535,20 @@ Strophe.addConnectionPlugin('rayo', ...@@ -440,16 +535,20 @@ Strophe.addConnectionPlugin('rayo',
var mixer = headers.mixer_name; var mixer = headers.mixer_name;
var call = { var call = {
digit: function(tone) {that.digit(callId, tone);}, digit: function(tone) {that.digit(callId, tone);},
hangup: function() {that.hangup(callId);}, redirect: function(to) {that.redirect(to, mixer, headers);},
answer: function() {that.answer(callId, mixer, headers);}, hangup: function() {that.hangup(callId);},
join: function() {that.join(mixer, headers);}, hold: function() {that.hold(callId);},
leave: function() {that.leave(mixer);}, answer: function() {that.answer(callId, mixer, headers, callFrom);},
mute: function(flag) {that.mute(callId, flag);}, join: function() {that.join(mixer, headers);},
leave: function() {that.leave(mixer);},
mute: function(flag) {that.mute(callId, flag);},
private: function() {that.private(callId, !this.privateCall);},
from: callFrom, from: callFrom,
to: callTo, to: callTo,
id: callId id: callId,
privateCall: false
} }
if (that.callbacks && that.callbacks.onOffer) that.callbacks.onOffer(call, headers); if (that.callbacks && that.callbacks.onOffer) that.callbacks.onOffer(call, headers);
...@@ -466,6 +565,9 @@ Strophe.addConnectionPlugin('rayo', ...@@ -466,6 +565,9 @@ Strophe.addConnectionPlugin('rayo',
if (value) iq.c("header", {name: name, value: value}).up(); if (value) iq.c("header", {name: name, value: value}).up();
} }
iq.c("header", {name: "caller_id", value: callFrom}).up();
iq.c("header", {name: "mixer_name", value: mixer}).up();
//console.log(iq.toString()); //console.log(iq.toString());
that._connection.sendIQ(iq, null, function(error) that._connection.sendIQ(iq, null, function(error)
...@@ -543,7 +645,7 @@ Strophe.addConnectionPlugin('rayo', ...@@ -543,7 +645,7 @@ Strophe.addConnectionPlugin('rayo',
{ {
//console.log(presence); //console.log(presence);
if ($(this).attr('xmlns') == Strophe.NS.RAYO_CORE) if ($(this).attr('xmlns') == Strophe.NS.RAYO_HANDSET)
{ {
var callId = Strophe.getNodeFromJid(from); var callId = Strophe.getNodeFromJid(from);
if (that.callbacks && that.callbacks.onHold) that.callbacks.onHold(callId); if (that.callbacks && that.callbacks.onHold) that.callbacks.onHold(callId);
...@@ -554,7 +656,7 @@ Strophe.addConnectionPlugin('rayo', ...@@ -554,7 +656,7 @@ Strophe.addConnectionPlugin('rayo',
{ {
//console.log(presence); //console.log(presence);
if ($(this).attr('xmlns') == Strophe.NS.RAYO_CORE) if ($(this).attr('xmlns') == Strophe.NS.RAYO_HANDSET)
{ {
var callId = Strophe.getNodeFromJid(from); var callId = Strophe.getNodeFromJid(from);
if (that.callbacks && that.callbacks.onMute) that.callbacks.onMute(callId); if (that.callbacks && that.callbacks.onMute) that.callbacks.onMute(callId);
...@@ -565,15 +667,39 @@ Strophe.addConnectionPlugin('rayo', ...@@ -565,15 +667,39 @@ Strophe.addConnectionPlugin('rayo',
{ {
//console.log(presence); //console.log(presence);
if ($(this).attr('xmlns') == Strophe.NS.RAYO_CORE) if ($(this).attr('xmlns') == Strophe.NS.RAYO_HANDSET)
{ {
var callId = Strophe.getNodeFromJid(from); var callId = Strophe.getNodeFromJid(from);
if (that.callbacks && that.callbacks.offMute) that.callbacks.offMute(callId); if (that.callbacks && that.callbacks.offMute) that.callbacks.offMute(callId);
} }
});
$(presence).find('private').each(function()
{
//console.log(presence);
if ($(this).attr('xmlns') == Strophe.NS.RAYO_HANDSET)
{
var callId = Strophe.getNodeFromJid(from);
if (that.callbacks && that.callbacks.onPrivate) that.callbacks.onPrivate(callId);
}
});
$(presence).find('public').each(function()
{
//console.log(presence);
if ($(this).attr('xmlns') == Strophe.NS.RAYO_HANDSET)
{
var callId = Strophe.getNodeFromJid(from);
if (that.callbacks && that.callbacks.offPrivate) that.callbacks.offPrivate(callId);
}
}); });
$(presence).find('ringing').each(function() $(presence).find('ringing').each(function()
{ {
//console.log(presence);
if ($(this).attr('xmlns') == Strophe.NS.RAYO_CORE) if ($(this).attr('xmlns') == Strophe.NS.RAYO_CORE)
{ {
var callId = Strophe.getNodeFromJid(from); var callId = Strophe.getNodeFromJid(from);
...@@ -610,15 +736,17 @@ Strophe.addConnectionPlugin('rayo', ...@@ -610,15 +736,17 @@ Strophe.addConnectionPlugin('rayo',
var mixer = headers.mixer_name; var mixer = headers.mixer_name;
var call = { var call = {
digit: function(tone) {that.digit(callId, tone);}, digit: function(tone) {that.digit(callId, tone);},
hangup: function() {that.hangup(callId);}, hangup: function() {that.hangup(callId);},
answer: function() {that.answer(callId, mixer, headers);}, hold: function() {that.hold(callId);},
join: function() {that.join(mixer, headers);}, join: function() {that.join(mixer, headers);},
leave: function() {that.leave(mixer);}, leave: function() {that.leave(mixer);},
mute: function(flag) {that.mute(callId, flag);}, mute: function(flag) {that.mute(callId, flag);},
private: function() {that.private(callId, !this.privateCall);},
id: callId, id: callId,
from: Strophe.getNodeFromJid(jid) from: Strophe.getNodeFromJid(jid),
privateCall: false
} }
if (that.callbacks && that.callbacks.onHook) that.callbacks.onHook(); if (that.callbacks && that.callbacks.onHook) that.callbacks.onHook();
if (that.callbacks && that.callbacks.onBusy) that.callbacks.onBusy(call, headers); if (that.callbacks && that.callbacks.onBusy) that.callbacks.onBusy(call, headers);
......
...@@ -32,6 +32,7 @@ public class Handset extends BaseVerb { ...@@ -32,6 +32,7 @@ public class Handset extends BaseVerb {
public String mixer = null; public String mixer = null;
public String group = null; public String group = null;
public String sipuri = null; public String sipuri = null;
public String callId = null;
public Handset(String cryptoSuite, String localCrypto, String remoteCrypto, String codec, String stereo, String mixer) public Handset(String cryptoSuite, String localCrypto, String remoteCrypto, String codec, String stereo, String mixer)
{ {
......
...@@ -23,10 +23,7 @@ import org.dom4j.Element; ...@@ -23,10 +23,7 @@ import org.dom4j.Element;
import org.dom4j.Namespace; import org.dom4j.Namespace;
import org.dom4j.QName; import org.dom4j.QName;
import com.rayo.core.verb.OnHookCommand; import com.rayo.core.verb.*;
import com.rayo.core.verb.OffHookCommand;
import com.rayo.core.verb.Handset;
import com.rayo.core.verb.SayCompleteEvent;
import com.rayo.core.verb.SayCompleteEvent.Reason; import com.rayo.core.verb.SayCompleteEvent.Reason;
public class HandsetProvider extends BaseProvider { public class HandsetProvider extends BaseProvider {
...@@ -39,6 +36,11 @@ public class HandsetProvider extends BaseProvider { ...@@ -39,6 +36,11 @@ public class HandsetProvider extends BaseProvider {
private static final QName ONHOOK_QNAME = new QName("onhook", NAMESPACE); private static final QName ONHOOK_QNAME = new QName("onhook", NAMESPACE);
private static final QName OFFHOOK_QNAME = new QName("offhook", NAMESPACE); private static final QName OFFHOOK_QNAME = new QName("offhook", NAMESPACE);
private static final QName PRIVATE_QNAME = new QName("private", NAMESPACE);
private static final QName PUBLIC_QNAME = new QName("public", NAMESPACE);
private static final QName MUTE_QNAME = new QName("mute", NAMESPACE);
private static final QName UNMUTE_QNAME = new QName("unmute", NAMESPACE);
private static final QName HOLD_QNAME = new QName("hold", NAMESPACE);
@Override @Override
protected Object processElement(Element element) throws Exception protected Object processElement(Element element) throws Exception
...@@ -49,14 +51,54 @@ public class HandsetProvider extends BaseProvider { ...@@ -49,14 +51,54 @@ public class HandsetProvider extends BaseProvider {
} else if (OFFHOOK_QNAME.equals(element.getQName())) { } else if (OFFHOOK_QNAME.equals(element.getQName())) {
return buildOffHookCommand(element); return buildOffHookCommand(element);
} else if (PRIVATE_QNAME.equals(element.getQName())) {
return buildPrivateCommand(element);
} else if (PUBLIC_QNAME.equals(element.getQName())) {
return buildPublicCommand(element);
} else if (MUTE_QNAME.equals(element.getQName())) {
return buildMuteCommand(element);
} else if (UNMUTE_QNAME.equals(element.getQName())) {
return buildUnmuteCommand(element);
} else if (HOLD_QNAME.equals(element.getQName())) {
return buildHoldCommand(element);
} else if (element.getNamespace().equals(RAYO_COMPONENT_NAMESPACE)) { } else if (element.getNamespace().equals(RAYO_COMPONENT_NAMESPACE)) {
return buildCompleteCommand(element); return buildCompleteCommand(element);
} }
return null; return null;
} }
private Object buildCompleteCommand(Element element) { private Object buildPrivateCommand(Element element)
{
return new PrivateCommand();
}
private Object buildPublicCommand(Element element)
{
return new PublicCommand();
}
private Object buildMuteCommand(Element element)
{
return new MuteCommand();
}
private Object buildUnmuteCommand(Element element)
{
return new UnmuteCommand();
}
private Object buildHoldCommand(Element element)
{
return new HoldCommand();
}
private Object buildCompleteCommand(Element element)
{
Element reasonElement = (Element)element.elements().get(0); Element reasonElement = (Element)element.elements().get(0);
String reasonValue = reasonElement.getName().toUpperCase(); String reasonValue = reasonElement.getName().toUpperCase();
Reason reason = Reason.valueOf(reasonValue); Reason reason = Reason.valueOf(reasonValue);
...@@ -87,6 +129,7 @@ public class HandsetProvider extends BaseProvider { ...@@ -87,6 +129,7 @@ public class HandsetProvider extends BaseProvider {
} }
handset.group = element.attributeValue("group"); handset.group = element.attributeValue("group");
handset.callId = element.attributeValue("callid");
OffHookCommand command = new OffHookCommand(); OffHookCommand command = new OffHookCommand();
command.setHandset(handset); command.setHandset(handset);
...@@ -112,6 +155,24 @@ public class HandsetProvider extends BaseProvider { ...@@ -112,6 +155,24 @@ public class HandsetProvider extends BaseProvider {
} else if (object instanceof SayCompleteEvent) { } else if (object instanceof SayCompleteEvent) {
createHandsetCompleteEvent((SayCompleteEvent) object, document); createHandsetCompleteEvent((SayCompleteEvent) object, document);
} else if (object instanceof OnHoldEvent) {
createOnHoldEvent((OnHoldEvent) object, document);
} 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);
} else if (object instanceof PrivateEvent) {
createPrivateEvent((PrivateEvent) object, document);
} else if (object instanceof PublicEvent) {
createPublicEvent((PublicEvent) object, document);
} }
} }
...@@ -128,11 +189,44 @@ public class HandsetProvider extends BaseProvider { ...@@ -128,11 +189,44 @@ public class HandsetProvider extends BaseProvider {
} }
private void createOnHookCommand(OnHookCommand command, Document document) throws Exception { private void createOnHookCommand(OnHookCommand command, Document document) throws Exception
{
document.addElement(new QName("onhook", NAMESPACE)); document.addElement(new QName("onhook", NAMESPACE));
} }
private void createHandsetCompleteEvent(SayCompleteEvent event, Document document) throws Exception { private void createHandsetCompleteEvent(SayCompleteEvent event, Document document) throws Exception
{
addCompleteElement(document, event, COMPLETE_NAMESPACE); addCompleteElement(document, event, COMPLETE_NAMESPACE);
} }
private void createOnHoldEvent(OnHoldEvent onHold, Document document)
{
document.addElement(new QName("onhold", NAMESPACE));
}
private void createOffHoldEvent(OffHoldEvent offHold, Document document)
{
document.addElement(new QName("offhold", NAMESPACE));
}
private void createMutedEvent(MutedEvent muted, Document document)
{
document.addElement(new QName("onmute", NAMESPACE));
}
private void createUnmutedEvent(UnmutedEvent unmuted, Document document)
{
document.addElement(new QName("offmute", NAMESPACE));
}
private void createPrivateEvent(PrivateEvent event, Document document)
{
document.addElement(new QName("private", NAMESPACE));
}
private void createPublicEvent(PublicEvent event, Document document)
{
document.addElement(new QName("public", NAMESPACE));
}
} }
...@@ -63,6 +63,10 @@ public class ConferenceManager { ...@@ -63,6 +63,10 @@ public class ConferenceManager {
private boolean isFirstMember = true; private boolean isFirstMember = true;
private boolean privateCall = false;
private String groupName = null;
/* /*
* If useSingleSender is true, a single * If useSingleSender is true, a single
* conferenceSender will be used for all conferences. * conferenceSender will be used for all conferences.
...@@ -623,18 +627,39 @@ public class ConferenceManager { ...@@ -623,18 +627,39 @@ public class ConferenceManager {
* audio treatment. * audio treatment.
* @return true if this is the first member, false otherwise * @return true if this is the first member, false otherwise
*/ */
public boolean isFirstMember() { public boolean isFirstMember()
synchronized (memberList) { {
if (isFirstMember == false) { synchronized (memberList) {
return false; if (isFirstMember == false) {
} return false;
}
isFirstMember = false; isFirstMember = false;
return memberList.isEmpty(); return memberList.isEmpty();
} }
} }
public boolean isPrivateCall()
{
return privateCall;
}
public void setPrivateCall(boolean privateCall)
{
this.privateCall = privateCall;
}
public String getGroupName()
{
return groupName;
}
public void setGroupName(String groupName)
{
this.groupName = groupName;
}
/** /**
* Add a new member to the conference * Add a new member to the conference
* *
......
...@@ -26,9 +26,13 @@ import org.jivesoftware.openfire.session.ClientSession; ...@@ -26,9 +26,13 @@ import org.jivesoftware.openfire.session.ClientSession;
import org.jivesoftware.openfire.muc.*; import org.jivesoftware.openfire.muc.*;
import org.jivesoftware.openfire.muc.spi.*; import org.jivesoftware.openfire.muc.spi.*;
import org.jivesoftware.openfire.XMPPServer; import org.jivesoftware.openfire.XMPPServer;
import org.jivesoftware.openfire.http.HttpBindManager;
import org.jivesoftware.openfire.group.Group; import org.jivesoftware.openfire.group.Group;
import org.jivesoftware.openfire.group.GroupManager; import org.jivesoftware.openfire.group.GroupManager;
import org.jivesoftware.openfire.group.GroupNotFoundException; import org.jivesoftware.openfire.group.GroupNotFoundException;
import org.jivesoftware.openfire.handler.IQHandler;
import org.jivesoftware.openfire.IQHandlerInfo;
import org.jivesoftware.openfire.auth.UnauthorizedException;
import org.jivesoftware.util.JiveGlobals; import org.jivesoftware.util.JiveGlobals;
...@@ -36,6 +40,9 @@ import org.xmpp.packet.JID; ...@@ -36,6 +40,9 @@ import org.xmpp.packet.JID;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.xmpp.component.Component;
import org.xmpp.component.ComponentException;
import org.xmpp.component.ComponentManager;
import org.xmpp.component.ComponentManagerFactory; import org.xmpp.component.ComponentManagerFactory;
import org.xmpp.component.AbstractComponent; import org.xmpp.component.AbstractComponent;
import org.xmpp.jnodes.*; import org.xmpp.jnodes.*;
...@@ -61,11 +68,14 @@ import org.voicebridge.*; ...@@ -61,11 +68,14 @@ import org.voicebridge.*;
public class RayoComponent extends AbstractComponent public class RayoComponent extends AbstractComponent
implements TreatmentDoneListener, implements TreatmentDoneListener,
CallEventListener, CallEventListener {
DirectCallEventListener {
private static final Logger Log = LoggerFactory.getLogger(RayoComponent.class); private static final Logger Log = LoggerFactory.getLogger(RayoComponent.class);
private static final String RAYO_CORE = "urn:xmpp:rayo:1";
private static final String RAYO_SAY = "urn:xmpp:tropo:say:1";
private static final String RAYO_HANDSET = "urn:xmpp:rayo:handset:1";
private static final String HOST = "host"; private static final String HOST = "host";
private static final String LOCAL_PORT = "localport"; private static final String LOCAL_PORT = "localport";
private static final String REMOTE_PORT = "remoteport"; private static final String REMOTE_PORT = "remoteport";
...@@ -81,26 +91,53 @@ public class RayoComponent extends AbstractComponent ...@@ -81,26 +91,53 @@ public class RayoComponent extends AbstractComponent
private SayProvider sayProvider = null; private SayProvider sayProvider = null;
private HandsetProvider handsetProvider = null; private HandsetProvider handsetProvider = null;
public RayoComponent(final RayoPlugin plugin) public RayoComponent(final RayoPlugin plugin)
{ {
self = this; self = this;
this.plugin = plugin; this.plugin = plugin;
rayoProvider = new RayoProvider(); }
public void doStart()
{
Log.info("RayoComponent initialize " + jid);
XMPPServer server = XMPPServer.getInstance();
server.getIQDiscoInfoHandler().addServerFeature(RAYO_CORE);
rayoProvider = new RayoProvider();
rayoProvider.setValidator(new Validator()); rayoProvider.setValidator(new Validator());
server.getIQDiscoInfoHandler().addServerFeature(RAYO_SAY);
sayProvider = new SayProvider(); sayProvider = new SayProvider();
sayProvider.setValidator(new Validator()); sayProvider.setValidator(new Validator());
server.getIQDiscoInfoHandler().addServerFeature(RAYO_HANDSET);
handsetProvider = new HandsetProvider(); handsetProvider = new HandsetProvider();
handsetProvider.setValidator(new Validator()); handsetProvider.setValidator(new Validator());
Plugin fastpath = XMPPServer.getInstance().getPluginManager().getPlugin("fastpath"); createIQHandlers();
Plugin fastpath = server.getPluginManager().getPlugin("fastpath");
if (fastpath != null) if (fastpath != null)
{ {
Log.info("RayoComponent found Fastpath"); Log.info("RayoComponent found Fastpath");
} }
} }
public void doStop()
{
Log.info("RayoComponent shutdown ");
XMPPServer server = XMPPServer.getInstance();
server.getIQDiscoInfoHandler().removeServerFeature(RAYO_CORE);
server.getIQDiscoInfoHandler().removeServerFeature(RAYO_SAY);
server.getIQDiscoInfoHandler().removeServerFeature(RAYO_HANDSET);
destroyIQHandlers();
}
public String getName() { public String getName() {
return "rayo"; return "rayo";
...@@ -112,7 +149,7 @@ public class RayoComponent extends AbstractComponent ...@@ -112,7 +149,7 @@ public class RayoComponent extends AbstractComponent
@Override @Override
protected String[] discoInfoFeatureNamespaces() { protected String[] discoInfoFeatureNamespaces() {
return new String[]{"urn:xmpp:rayo:1"}; return new String[]{RAYO_CORE};
} }
@Override @Override
...@@ -128,7 +165,7 @@ public class RayoComponent extends AbstractComponent ...@@ -128,7 +165,7 @@ public class RayoComponent extends AbstractComponent
try { try {
if ("urn:xmpp:rayo:handset:1".equals(namespace)) { if (RAYO_HANDSET.equals(namespace)) {
IQ reply = null; IQ reply = null;
Object object = handsetProvider.fromXML(element); Object object = handsetProvider.fromXML(element);
...@@ -140,11 +177,26 @@ public class RayoComponent extends AbstractComponent ...@@ -140,11 +177,26 @@ public class RayoComponent extends AbstractComponent
} else if (object instanceof OffHookCommand) { } else if (object instanceof OffHookCommand) {
OffHookCommand command = (OffHookCommand) object; OffHookCommand command = (OffHookCommand) object;
reply = handleOnOffHookCommand(command, iq); reply = handleOnOffHookCommand(command, iq);
} else if (object instanceof MuteCommand) {
reply = handleMuteCommand((MuteCommand) object, iq);
} else if (object instanceof UnmuteCommand) {
reply = handleMuteCommand((UnmuteCommand) object, iq);
} else if (object instanceof HoldCommand) {
reply = handleHoldCommand((HoldCommand) object, iq);
} else if (object instanceof PrivateCommand) {
reply = handlePrivateCommand(object, iq);
} else if (object instanceof PublicCommand) {
reply = handlePrivateCommand(object, iq);
} }
return reply; return reply;
} }
if ("urn:xmpp:tropo:say:1".equals(namespace)) { if (RAYO_SAY.equals(namespace)) {
IQ reply = null; IQ reply = null;
Object object = sayProvider.fromXML(element); Object object = sayProvider.fromXML(element);
...@@ -161,26 +213,12 @@ public class RayoComponent extends AbstractComponent ...@@ -161,26 +213,12 @@ public class RayoComponent extends AbstractComponent
return reply; return reply;
} }
if ("urn:xmpp:rayo:1".equals(namespace)) { if (RAYO_CORE.equals(namespace)) {
IQ reply = null; IQ reply = null;
Object object = rayoProvider.fromXML(element); Object object = rayoProvider.fromXML(element);
if (object instanceof ConnectCommand) { if (object instanceof JoinCommand) {
} 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); reply = handleJoinCommand((JoinCommand) object, iq);
} else if (object instanceof UnjoinCommand) { } else if (object instanceof UnjoinCommand) {
...@@ -199,6 +237,13 @@ public class RayoComponent extends AbstractComponent ...@@ -199,6 +237,13 @@ public class RayoComponent extends AbstractComponent
// implemented as hangup on client // implemented as hangup on client
} else if (object instanceof RedirectCommand) { } else if (object instanceof RedirectCommand) {
RedirectCommand redirect = (RedirectCommand) object;
DialCommand dial = new DialCommand();
dial.setTo(redirect.getTo());
dial.setFrom(new URI("xmpp:" + iq.getFrom()));
dial.setHeaders(redirect.getHeaders());
reply = handleDialCommand((DialCommand) dial, iq);
} else if (object instanceof DialCommand) { } else if (object instanceof DialCommand) {
reply = handleDialCommand((DialCommand) object, iq); reply = handleDialCommand((DialCommand) object, iq);
...@@ -225,6 +270,26 @@ public class RayoComponent extends AbstractComponent ...@@ -225,6 +270,26 @@ public class RayoComponent extends AbstractComponent
} }
} }
private IQ handleHoldCommand(Object object, IQ iq)
{
Log.info("RayoComponent handleHoldCommand");
IQ reply = IQ.createResultIQ(iq);
String callId = iq.getTo().getNode(); // far party
CallHandler handler = CallHandler.findCall(callId);
if (handler != null)
{
handler.getCallParticipant().setHeld(true);
} else {
reply.setError(PacketError.Condition.item_not_found);
}
return reply;
}
private IQ handleMuteCommand(Object object, IQ iq) private IQ handleMuteCommand(Object object, IQ iq)
{ {
...@@ -233,7 +298,7 @@ public class RayoComponent extends AbstractComponent ...@@ -233,7 +298,7 @@ public class RayoComponent extends AbstractComponent
boolean muted = object instanceof MuteCommand; boolean muted = object instanceof MuteCommand;
IQ reply = IQ.createResultIQ(iq); IQ reply = IQ.createResultIQ(iq);
String callId = JID.escapeNode(iq.getFrom().toString()); String callId = JID.escapeNode(iq.getFrom().toString()); // handset
CallHandler handler = CallHandler.findCall(callId); CallHandler handler = CallHandler.findCall(callId);
...@@ -266,10 +331,72 @@ public class RayoComponent extends AbstractComponent ...@@ -266,10 +331,72 @@ public class RayoComponent extends AbstractComponent
if (muted) if (muted)
{ {
MutedEvent event = new MutedEvent(); MutedEvent event = new MutedEvent();
presence.getElement().add(toXML(event)); presence.getElement().add(handsetProvider.toXML(event));
} else { } else {
UnmutedEvent event = new UnmutedEvent(); UnmutedEvent event = new UnmutedEvent();
presence.getElement().add(toXML(event)); presence.getElement().add(handsetProvider.toXML(event));
}
sendPacket(presence);
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
} else {
reply.setError(PacketError.Condition.item_not_found);
}
return reply;
}
private IQ handlePrivateCommand(Object object, IQ iq)
{
Log.info("RayoComponent handlePrivateCommand");
boolean privateCall = object instanceof PrivateCommand;
IQ reply = IQ.createResultIQ(iq);
String callId = JID.escapeNode(iq.getFrom().toString()); // handset
CallHandler handler = CallHandler.findCall(callId);
if (handler != null)
{
try {
ConferenceManager conferenceManager = ConferenceManager.findConferenceManager(handler.getCallParticipant().getConferenceId());
conferenceManager.setPrivateCall(privateCall);
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 handlePrivateCommand route event to " + target);
if (target != null)
{
Presence presence = new Presence();
presence.setFrom(callId + "@rayo." + getDomain());
presence.setTo(target);
if (privateCall)
{
PrivateEvent event = new PrivateEvent();
presence.getElement().add(handsetProvider.toXML(event));
} else {
PublicEvent event = new PublicEvent();
presence.getElement().add(handsetProvider.toXML(event));
} }
sendPacket(presence); sendPacket(presence);
...@@ -293,15 +420,15 @@ public class RayoComponent extends AbstractComponent ...@@ -293,15 +420,15 @@ public class RayoComponent extends AbstractComponent
Log.info("RayoComponent handleOnOffHookCommand"); Log.info("RayoComponent handleOnOffHookCommand");
IQ reply = IQ.createResultIQ(iq); IQ reply = IQ.createResultIQ(iq);
String callId = JID.escapeNode(iq.getFrom().toString()); String handsetId = JID.escapeNode(iq.getFrom().toString());
if (object instanceof OnHookCommand) if (object instanceof OnHookCommand)
{ {
CallHandler handler = CallHandler.findCall(callId); CallHandler handler = CallHandler.findCall(handsetId);
if (handler != null) if (handler != null)
{ {
handleOnOffHook(callId, object, plugin.getRelayChannel(callId)); handleOnOffHook(handsetId, object, plugin.getRelayChannel(handsetId), reply);
} else { } else {
reply.setError(PacketError.Condition.item_not_found); reply.setError(PacketError.Condition.item_not_found);
...@@ -317,7 +444,7 @@ public class RayoComponent extends AbstractComponent ...@@ -317,7 +444,7 @@ public class RayoComponent extends AbstractComponent
if (channel != null) if (channel != null)
{ {
final Element childElement = reply.setChildElement("ref", "urn:xmpp:rayo:1"); final Element childElement = reply.setChildElement("ref", RAYO_CORE);
childElement.addAttribute(HOST, LocalIPResolver.getLocalIP()); childElement.addAttribute(HOST, LocalIPResolver.getLocalIP());
childElement.addAttribute(LOCAL_PORT, Integer.toString(channel.getPortA())); childElement.addAttribute(LOCAL_PORT, Integer.toString(channel.getPortA()));
...@@ -327,7 +454,7 @@ public class RayoComponent extends AbstractComponent ...@@ -327,7 +454,7 @@ public class RayoComponent extends AbstractComponent
Log.debug("Created WebRTC handset channel {}:{}, {}:{}, {}:{}", new Object[]{HOST, LocalIPResolver.getLocalIP(), LOCAL_PORT, Integer.toString(channel.getPortA()), REMOTE_PORT, Integer.toString(channel.getPortB())}); Log.debug("Created WebRTC handset channel {}:{}, {}:{}, {}:{}", new Object[]{HOST, LocalIPResolver.getLocalIP(), LOCAL_PORT, Integer.toString(channel.getPortA()), REMOTE_PORT, Integer.toString(channel.getPortB())});
handleOnOffHook(callId, object, channel); handleOnOffHook(handsetId, object, channel, reply);
} else { } else {
reply.setError(PacketError.Condition.internal_server_error); reply.setError(PacketError.Condition.internal_server_error);
...@@ -335,14 +462,14 @@ public class RayoComponent extends AbstractComponent ...@@ -335,14 +462,14 @@ public class RayoComponent extends AbstractComponent
} else { // SIP handset } else { // SIP handset
final Element childElement = reply.setChildElement("ref", "urn:xmpp:rayo:1"); final Element childElement = reply.setChildElement("ref", RAYO_CORE);
childElement.addAttribute(ID, callId); childElement.addAttribute(ID, handsetId);
childElement.addAttribute(URI, "handset:" + callId + "@rayo." + getDomain() + "/" + iq.getFrom().getNode()); childElement.addAttribute(URI, "handset:" + handsetId + "@rayo." + getDomain() + "/" + iq.getFrom().getNode());
Log.info("Created SIP handset channel " + handset.sipuri); Log.info("Created SIP handset channel " + handset.sipuri);
handleOnOffHook(callId, object, null); handleOnOffHook(handsetId, object, null, reply);
} }
} }
...@@ -350,14 +477,14 @@ public class RayoComponent extends AbstractComponent ...@@ -350,14 +477,14 @@ public class RayoComponent extends AbstractComponent
} }
private void handleOnOffHook(String callId, Object object, RelayChannel channel) private void handleOnOffHook(String handsetId, Object object, RelayChannel channel, IQ reply)
{ {
final boolean flag = object instanceof OnHookCommand; final boolean flag = object instanceof OnHookCommand;
Log.info("RayoComponent handleOnOffHook " + flag); Log.info("RayoComponent handleOnOffHook " + flag);
try { try {
CallHandler handler = CallHandler.findCall(callId); CallHandler handler = CallHandler.findCall(handsetId);
if (handler != null) if (handler != null)
{ {
...@@ -375,40 +502,58 @@ public class RayoComponent extends AbstractComponent ...@@ -375,40 +502,58 @@ public class RayoComponent extends AbstractComponent
mediaPreference = "PCM/48000/2"; mediaPreference = "PCM/48000/2";
CallParticipant cp = new CallParticipant(); CallParticipant cp = new CallParticipant();
cp.setCallId(callId); cp.setCallId(handsetId);
cp.setConferenceId(handset.mixer); cp.setConferenceId(handset.mixer);
cp.setDisplayName("rayo-handset-" + System.currentTimeMillis()); cp.setDisplayName("rayo-handset-" + System.currentTimeMillis());
cp.setName(cp.getDisplayName()); cp.setName(cp.getDisplayName());
cp.setVoiceDetection(true); cp.setVoiceDetection(true);
cp.setCallOwner(JID.unescapeNode(callId)); cp.setCallOwner(JID.unescapeNode(handsetId));
String label = (new JID(cp.getCallOwner())).getNode();
if (handset.group != null && ! "".equals(handset.group)) if (handset.group != null && ! "".equals(handset.group))
{ {
// set for new or existing conference label = handset.group;
ConferenceManager.getConference(handset.mixer, mediaPreference, handset.group, false);
ConferenceManager.setDisplayName(handset.mixer, handset.group);
} }
if (channel == null) ConferenceManager cm = ConferenceManager.getConference(handset.mixer, mediaPreference, label, false);
{
cp.setMediaPreference("PCMU/8000/1");
cp.setPhoneNumber(handset.sipuri);
cp.setAutoAnswer(true);
cp.setProtocol("SIP");
} else { if (handset.callId != null && "".equals(handset.callId) == false)
cp.setMediaPreference(mediaPreference); {
cp.setRelayChannel(channel); cm.setCallId(handset.callId); // set answering far party call id for mixer
cp.setProtocol("WebRtc");
} }
OutgoingCallHandler callHandler = new OutgoingCallHandler(this, cp); if (handset.group != null && ! "".equals(handset.group))
callHandler.start(); {
cm.setGroupName(handset.group);
}
if (channel != null) if (cm.isPrivateCall() == false || cm.getMemberList().size() < 2)
{ {
channel.setCallHandler(callHandler); if (channel == null)
{
cp.setMediaPreference("PCMU/8000/1");
cp.setPhoneNumber(handset.sipuri);
cp.setAutoAnswer(true);
cp.setProtocol("SIP");
} else {
cp.setMediaPreference(mediaPreference);
cp.setRelayChannel(channel);
cp.setProtocol("WebRtc");
}
OutgoingCallHandler callHandler = new OutgoingCallHandler(this, cp);
callHandler.start();
if (channel != null)
{
channel.setCallHandler(callHandler);
}
} else {
reply.setError(PacketError.Condition.not_allowed);
} }
} }
...@@ -432,7 +577,7 @@ public class RayoComponent extends AbstractComponent ...@@ -432,7 +577,7 @@ public class RayoComponent extends AbstractComponent
try { try {
callHandler.playTreatmentToCall(treatmentId, this); callHandler.playTreatmentToCall(treatmentId, this);
final Element childElement = reply.setChildElement("ref", "urn:xmpp:rayo:1"); final Element childElement = reply.setChildElement("ref", RAYO_CORE);
childElement.addAttribute(URI, (String) "xmpp:" + entityId + "@rayo." + getDomain() + "/" + treatmentId); childElement.addAttribute(URI, (String) "xmpp:" + entityId + "@rayo." + getDomain() + "/" + treatmentId);
} catch (Exception e1) { } catch (Exception e1) {
...@@ -447,7 +592,7 @@ public class RayoComponent extends AbstractComponent ...@@ -447,7 +592,7 @@ public class RayoComponent extends AbstractComponent
try { try {
conferenceManager.addTreatment(treatmentId); conferenceManager.addTreatment(treatmentId);
final Element childElement = reply.setChildElement("ref", "urn:xmpp:rayo:1"); final Element childElement = reply.setChildElement("ref", RAYO_CORE);
childElement.addAttribute(URI, (String) "xmpp:" + entityId + "@rayo." + getDomain() + "/" + treatmentId); childElement.addAttribute(URI, (String) "xmpp:" + entityId + "@rayo." + getDomain() + "/" + treatmentId);
} catch (Exception e2) { } catch (Exception e2) {
...@@ -499,23 +644,32 @@ public class RayoComponent extends AbstractComponent ...@@ -499,23 +644,32 @@ public class RayoComponent extends AbstractComponent
private IQ handleAcceptCommand(AcceptCommand command, IQ iq) private IQ handleAcceptCommand(AcceptCommand command, IQ iq)
{ {
String callId = iq.getTo().getNode(); Map<String, String> headers = command.getHeaders();
Log.info("RayoComponent handleAcceptCommand " + iq.getFrom() + " " + callId);
String callId = iq.getTo().getNode(); // destination JID escaped
String callerId = headers.get("caller_id"); // source JID
String mixer = headers.get("mixer_name");
Log.info("RayoComponent handleAcceptCommand " + callerId + " " + callId + " " + mixer);
IQ reply = IQ.createResultIQ(iq); IQ reply = IQ.createResultIQ(iq);
JID callJID = getJID(callId); JID callJID = getJID(callId);
if (callJID != null) // only for XMPP calls if (callJID != null) // only for XMPP calls
{ {
Map<String, String> headers = command.getHeaders(); if (mixer != null)
headers.put("call_protocol", "XMPP"); {
headers.put("call_protocol", "XMPP");
callerId = callerId.substring(5); // remove xmpp: prefix
Presence presence = new Presence(); Presence presence = new Presence();
presence.setFrom(iq.getTo()); presence.setFrom(iq.getTo());
presence.setTo(callJID); presence.setTo(callerId);
presence.getElement().add(rayoProvider.toXML(new RingingEvent(null, headers))); presence.getElement().add(rayoProvider.toXML(new RingingEvent(null, headers)));
sendPacket(presence); sendPacket(presence);
} else reply.setError(PacketError.Condition.item_not_found);
} }
return reply; return reply;
...@@ -523,58 +677,65 @@ public class RayoComponent extends AbstractComponent ...@@ -523,58 +677,65 @@ public class RayoComponent extends AbstractComponent
private IQ handleAnswerCommand(AnswerCommand command, IQ iq) private IQ handleAnswerCommand(AnswerCommand command, IQ iq)
{ {
String callId = iq.getTo().getNode(); Map<String, String> headers = command.getHeaders();
Log.info("RayoComponent AnswerCommand " + iq.getFrom() + " " + callId);
IQ reply = IQ.createResultIQ(iq); IQ reply = IQ.createResultIQ(iq);
JID callJID = getJID(callId);
Map<String, String> headers = command.getHeaders(); String callId = iq.getTo().getNode(); // destination JID escaped
CallHandler callHandler = null; String callerId = headers.get("caller_id"); // source JID
if (callJID != null) // XMPP call Log.info("RayoComponent AnswerCommand " + callerId + " " + callId);
if (callerId != null)
{ {
headers.put("call_protocol", "XMPP"); JID callJID = getJID(callId);
headers.put("call_owner", callJID.toString());
headers.put("call_action", "join");
try { CallHandler callHandler = null;
Presence presence1 = new Presence(); //to caller CallHandler handsetHandler = null;
presence1.setFrom(iq.getTo());
presence1.setTo(callJID);
presence1.getElement().add(rayoProvider.toXML(new AnsweredEvent(null, headers)));
sendPacket(presence1);
callHandler = CallHandler.findCall(callId); if (callJID != null) // XMPP call
{
callerId = callerId.substring(5); // remove xmpp: prefix
} catch (Exception e) { headers.put("call_protocol", "XMPP");
reply.setError(PacketError.Condition.item_not_found); headers.put("call_owner", callerId);
e.printStackTrace(); headers.put("call_action", "join");
}
} else { try {
Presence presence1 = new Presence(); //to caller
presence1.setFrom(iq.getTo());
presence1.setTo(callerId);
presence1.getElement().add(rayoProvider.toXML(new AnsweredEvent(null, headers)));
sendPacket(presence1);
callHandler = CallHandler.findCall(callId); // SIP call; callHandler = CallHandler.findCall(callId);
} handsetHandler = CallHandler.findCall(JID.escapeNode(callerId));
if (callHandler != null) } catch (Exception e) {
{ reply.setError(PacketError.Condition.item_not_found);
Log.info("RayoComponent handleAnswerCommand found call handler " + callHandler); e.printStackTrace();
}
} else {
CallHandler handsetHandler = CallHandler.findCall(JID.escapeNode(iq.getFrom().toString())); callHandler = CallHandler.findCall(callId); // SIP call;
handsetHandler = CallHandler.findCall(JID.escapeNode(iq.getFrom().toString()));
}
if (handsetHandler != null) if (callHandler != null && handsetHandler != null)
{ {
Log.info("RayoComponent handleAnswerCommand found handset handler " + handsetHandler); CallParticipant cp = callHandler.getCallParticipant();
CallParticipant hp = handsetHandler.getCallParticipant();
try { Log.info("RayoComponent handleAnswerCommand found call handlers " + cp.getCallId() + " " + hp.getCallId());
CallParticipant cp = callHandler.getCallParticipant();
CallParticipant hp = handsetHandler.getCallParticipant();
hp.setFarParty(cp); try {
long start = System.currentTimeMillis();
cp.setStartTimestamp(start);
cp.setHandset(hp); cp.setHandset(hp);
hp.setFarParty(cp);
hp.setStartTimestamp(start);
cp.setStartTimestamp(System.currentTimeMillis());
cp.setHeaders(headers); cp.setHeaders(headers);
String recording = cp.getConferenceId() + "-" + cp.getStartTimestamp() + ".au"; String recording = cp.getConferenceId() + "-" + cp.getStartTimestamp() + ".au";
...@@ -585,21 +746,27 @@ public class RayoComponent extends AbstractComponent ...@@ -585,21 +746,27 @@ public class RayoComponent extends AbstractComponent
if (callJID != null) if (callJID != null)
{ {
source = callJID.getNode(); source = (new JID(callerId)).getNode();
Config.createCallRecord(source, recording, "xmpp:" + iq.getFrom(), cp.getStartTimestamp(), 0, "dialed") ; Config.createCallRecord(source, recording, "xmpp:" + iq.getFrom(), cp.getStartTimestamp(), 0, "dialed") ;
Config.createCallRecord(destination, recording, "xmpp:" + callJID, cp.getStartTimestamp(), 0, "received") ; Config.createCallRecord(destination, recording, "xmpp:" + callerId, cp.getStartTimestamp(), 0, "received");
sendMessage(new JID(callerId), iq.getFrom(), "Call started", recording);
} else { // incoming SIP } else { // incoming SIP
Config.createCallRecord(destination, recording, "sip:" + cp.getPhoneNumber(), cp.getStartTimestamp(), 0, "received") ; Config.createCallRecord(destination, recording, "sip:" + cp.getPhoneNumber(), cp.getStartTimestamp(), 0, "received") ;
sendMessage(iq.getFrom(), new JID(cp.getCallId() + "@" + getDomain()), "Call started", recording);
} }
} catch (ParseException e1) { } catch (ParseException e1) {
reply.setError(PacketError.Condition.internal_server_error); reply.setError(PacketError.Condition.internal_server_error);
} }
} else reply.setError(PacketError.Condition.item_not_found); } else reply.setError(PacketError.Condition.item_not_found);
} else reply.setError(PacketError.Condition.item_not_found); } else reply.setError(PacketError.Condition.item_not_found);
return reply; return reply;
} }
...@@ -720,20 +887,6 @@ public class RayoComponent extends AbstractComponent ...@@ -720,20 +887,6 @@ public class RayoComponent extends AbstractComponent
} }
private IQ handleDialCommand(DialCommand command, IQ iq) private IQ handleDialCommand(DialCommand command, IQ iq)
{
Log.info("RayoComponent handleDialCommand " + iq.getFrom());
Map<String, String> headers = command.getHeaders();
String bridged = headers.get("voicebridge");
if (bridged == null)
return handleHandsetDialCommand(command, iq);
else
return handleBridgedDialCommand(command, iq);
}
private IQ handleHandsetDialCommand(DialCommand command, IQ iq)
{ {
Log.info("RayoComponent handleHandsetDialCommand " + iq.getFrom()); Log.info("RayoComponent handleHandsetDialCommand " + iq.getFrom());
...@@ -809,11 +962,9 @@ public class RayoComponent extends AbstractComponent ...@@ -809,11 +962,9 @@ public class RayoComponent extends AbstractComponent
headers.put("mixer_name", hp.getConferenceId()); headers.put("mixer_name", hp.getConferenceId());
ConferenceManager.setCallId(hp.getConferenceId(), source);
if (findUser(destination.getNode()) != null) if (findUser(destination.getNode()) != null)
{ {
routeXMPPCall(reply, destination, source, calledName, headers); routeXMPPCall(reply, destination, source, calledName, headers, hp.getConferenceId());
} else { } else {
int count = 0; int count = 0;
...@@ -829,7 +980,7 @@ public class RayoComponent extends AbstractComponent ...@@ -829,7 +980,7 @@ public class RayoComponent extends AbstractComponent
for (ClientSession session : sessions) for (ClientSession session : sessions)
{ {
routeXMPPCall(reply, session.getAddress(), source, calledName, headers); routeXMPPCall(reply, session.getAddress(), source, calledName, headers, hp.getConferenceId());
count++; count++;
} }
} }
...@@ -847,7 +998,7 @@ public class RayoComponent extends AbstractComponent ...@@ -847,7 +998,7 @@ public class RayoComponent extends AbstractComponent
{ {
if (iq.getFrom().toBareJID().equals(role.getUserAddress().toBareJID()) == false) if (iq.getFrom().toBareJID().equals(role.getUserAddress().toBareJID()) == false)
{ {
routeXMPPCall(reply, role.getUserAddress(), source, calledName, headers); routeXMPPCall(reply, role.getUserAddress(), source, calledName, headers, hp.getConferenceId());
count++; count++;
} }
} }
...@@ -880,10 +1031,12 @@ public class RayoComponent extends AbstractComponent ...@@ -880,10 +1031,12 @@ public class RayoComponent extends AbstractComponent
return reply; return reply;
} }
private void routeXMPPCall(IQ reply, JID destination, String source, String calledName, Map<String, String> headers) private void routeXMPPCall(IQ reply, JID destination, String source, String calledName, Map<String, String> headers, String mixer)
{ {
String callId = JID.escapeNode(destination.toString());
Presence presence = new Presence(); Presence presence = new Presence();
presence.setFrom(source + "@rayo." + getDomain()); presence.setFrom(callId + "@rayo." + getDomain());
presence.setTo(destination); presence.setTo(destination);
OfferEvent offer = new OfferEvent(null); OfferEvent offer = new OfferEvent(null);
...@@ -905,144 +1058,15 @@ public class RayoComponent extends AbstractComponent ...@@ -905,144 +1058,15 @@ public class RayoComponent extends AbstractComponent
offer.setHeaders(headers); offer.setHeaders(headers);
final Element childElement = reply.setChildElement("ref", RAYO_CORE);
childElement.addAttribute(URI, (String) "xmpp:" + presence.getFrom());
childElement.addAttribute(ID, (String) callId);
presence.getElement().add(rayoProvider.toXML(offer)); presence.getElement().add(rayoProvider.toXML(offer));
sendPacket(presence); sendPacket(presence);
final Element childElement = reply.setChildElement("ref", "urn:xmpp:rayo:1");
childElement.addAttribute(URI, (String) "xmpp:" + destination);
childElement.addAttribute(ID, (String) JID.escapeNode(destination.toString()));
} }
private IQ handleBridgedDialCommand(DialCommand command, IQ iq)
{
Log.info("RayoComponent handleBridgedDialCommand " + iq.getFrom());
IQ reply = IQ.createResultIQ(iq);
Map<String, String> headers = command.getHeaders();
String from = command.getFrom().toString();
String to = command.getTo().toString();
boolean fromPhone = from.indexOf("sip:") == 0 || from.indexOf("tel:") == 0;
boolean toPhone = to.indexOf("sip:") == 0 || to.indexOf("tel:") == 0;
boolean toHandset = to.indexOf("handset:") == 0;
boolean fromHandset = from.indexOf("handset:") == 0;
String mixer = null;
String callerId = headers.get("caller_id");
String calledId = headers.get("called_id");
String callerName = headers.get("caller_name");
String calledName = headers.get("called_name");
JoinCommand join = command.getJoin();
if (join != null && join.getTo() != null)
{
if (join.getType() == JoinDestinationType.CALL) {
// TODO join.getTo()
} else {
mixer = join.getTo();
}
}
if (callerId == null) callerId = "rayo-caller-" + System.currentTimeMillis();
if (calledId == null) calledId = "rayo-called-" + System.currentTimeMillis();
CallParticipant cp = new CallParticipant();
cp.setVoiceDetection(true);
cp.setCallOwner(iq.getFrom().toString());
if (fromPhone && toPhone) // Phone to Phone
{
cp.setMediaPreference("PCMU/8000/1");
cp.setProtocol("SIP");
cp.setCallId(calledId);
cp.setPhoneNumber(to.substring(4));
cp.setName(calledName == null ? cp.getPhoneNumber() : calledName);
cp.setSecondPartyCallId(callerId);
cp.setSecondPartyNumber(from.substring(4));
cp.setSecondPartyName(callerName == null ? cp.getSecondPartyNumber() : callerName);
if (mixer == null) // Direct call, migrate to TwoParty later with Join to mixer
{
DirectCallHandler callHandler = new DirectCallHandler(cp, this);
callHandler.start();
} else { // TwoParty, use a mixer
if (mixer == null) mixer = cp.getPhoneNumber();
cp.setConferenceId(mixer);
TwoPartyCallHandler callHandler = new TwoPartyCallHandler(this, cp);
callHandler.start();
}
final Element childElement = reply.setChildElement("ref", "urn:xmpp:rayo:1");
childElement.addAttribute(URI, (String) "xmpp:" + calledId + "@rayo." + getDomain());
} else if (fromPhone && !toPhone) { // Phone to PC
cp.setMediaPreference("PCMU/8000/1");
cp.setProtocol("SIP");
cp.setCallId(callerId);
cp.setPhoneNumber(from.substring(4));
cp.setName(callerName == null ? cp.getPhoneNumber() : callerName);
if (mixer == null) mixer = cp.getPhoneNumber();
cp.setConferenceId(mixer);
if (toHandset) // (no offer)
{
//doPhoneAndPcCall(new JID(to.substring(8)), cp, reply, mixer);
} else { // (offer)
}
} else if (!fromPhone && toPhone) { // PC to Phone
cp.setMediaPreference("PCMU/8000/1");
cp.setProtocol("SIP");
cp.setCallId(calledId);
cp.setPhoneNumber(to.substring(4));
cp.setName(calledName == null ? cp.getPhoneNumber() : calledName);
if (mixer == null) mixer = cp.getPhoneNumber();
cp.setConferenceId(mixer);
if (fromHandset) // (no offer)
{
//doPhoneAndPcCall(new JID(from.substring(8)), cp, reply, mixer);
} else { // (offer)
}
} else if (!fromPhone && !toPhone) { // PC to PC
if (fromHandset && toHandset) // (intercom)
{
} else { // (private wire)
if (toHandset) // offer from
{
} else { // offer to
}
}
}
return reply;
}
private IQ doPhoneAndPcCall(String handsetId, CallParticipant cp, IQ reply) private IQ doPhoneAndPcCall(String handsetId, CallParticipant cp, IQ reply)
{ {
Log.info("RayoComponent doPhoneAndPcCall " + handsetId); Log.info("RayoComponent doPhoneAndPcCall " + handsetId);
...@@ -1061,7 +1085,7 @@ public class RayoComponent extends AbstractComponent ...@@ -1061,7 +1085,7 @@ public class RayoComponent extends AbstractComponent
outgoingCallHandler.start(); outgoingCallHandler.start();
final Element childElement = reply.setChildElement("ref", "urn:xmpp:rayo:1"); final Element childElement = reply.setChildElement("ref", RAYO_CORE);
childElement.addAttribute(URI, (String) "xmpp:" + cp.getCallId() + "@rayo." + getDomain()); childElement.addAttribute(URI, (String) "xmpp:" + cp.getCallId() + "@rayo." + getDomain());
childElement.addAttribute(ID, (String) cp.getCallId()); childElement.addAttribute(ID, (String) cp.getCallId());
...@@ -1084,20 +1108,23 @@ public class RayoComponent extends AbstractComponent ...@@ -1084,20 +1108,23 @@ public class RayoComponent extends AbstractComponent
hp.setFarParty(cp); hp.setFarParty(cp);
cp.setHandset(hp); cp.setHandset(hp);
long start = System.currentTimeMillis();
cp.setStartTimestamp(start);
hp.setStartTimestamp(start);
String mixer = hp.getConferenceId(); String mixer = hp.getConferenceId();
ConferenceManager conferenceManager = ConferenceManager.getConference(mixer, ConferenceManager conferenceManager = ConferenceManager.findConferenceManager(mixer);
hp.getMediaPreference(),
cp.getName(), false);
cp.setConferenceId(mixer); cp.setConferenceId(mixer);
cp.setCallId(mixer); cp.setCallId(mixer);
conferenceManager.setCallId(mixer); conferenceManager.setCallId(mixer);
cp.setStartTimestamp(System.currentTimeMillis());
String recording = mixer + "-" + cp.getStartTimestamp() + ".au"; String recording = mixer + "-" + cp.getStartTimestamp() + ".au";
conferenceManager.recordConference(true, recording, "au"); conferenceManager.recordConference(true, recording, "au");
Config.createCallRecord(cp.getDisplayName(), recording, cp.getPhoneNumber(), cp.getStartTimestamp(), 0, "dialed") ; Config.createCallRecord(cp.getDisplayName(), recording, cp.getPhoneNumber(), cp.getStartTimestamp(), 0, "dialed") ;
sendMessage(new JID(cp.getCallOwner()), new JID(cp.getCallId() + "@" + getDomain()), "Call started", recording);
} catch (ParseException e1) { } catch (ParseException e1) {
reply.setError(PacketError.Condition.internal_server_error); reply.setError(PacketError.Condition.internal_server_error);
} }
...@@ -1208,30 +1235,34 @@ public class RayoComponent extends AbstractComponent ...@@ -1208,30 +1235,34 @@ public class RayoComponent extends AbstractComponent
{ {
ConferenceMember member = (ConferenceMember) memberList.get(i); ConferenceMember member = (ConferenceMember) memberList.get(i);
CallHandler callHandler = member.getCallHandler(); CallHandler callHandler = member.getCallHandler();
CallParticipant cp = callHandler.getCallParticipant();
String target = cp.getCallOwner(); if (callHandler != null)
{
CallParticipant cp = callHandler.getCallParticipant();
Log.info( "RayoComponent broadcastSpeaking checking " + target); String target = cp.getCallOwner();
if (target != null && callId.equals(cp.getCallId()) == false) Log.info( "RayoComponent broadcastSpeaking checking " + target);
{
Presence presence = new Presence();
presence.setFrom(callId + "@rayo." + getDomain());
presence.setTo(target);
if (startSpeaking) if (target != null && callId.equals(cp.getCallId()) == false)
{ {
StartedSpeakingEvent speaker = new StartedSpeakingEvent(); Presence presence = new Presence();
speaker.setSpeakerId(callId); presence.setFrom(callId + "@rayo." + getDomain());
presence.getElement().add(rayoProvider.toXML(speaker)); presence.setTo(target);
} else {
StoppedSpeakingEvent speaker = new StoppedSpeakingEvent();
speaker.setSpeakerId(callId);
presence.getElement().add(rayoProvider.toXML(speaker));
}
sendPacket(presence); if (startSpeaking)
{
StartedSpeakingEvent speaker = new StartedSpeakingEvent();
speaker.setSpeakerId(callId);
presence.getElement().add(rayoProvider.toXML(speaker));
} else {
StoppedSpeakingEvent speaker = new StoppedSpeakingEvent();
speaker.setSpeakerId(callId);
presence.getElement().add(rayoProvider.toXML(speaker));
}
sendPacket(presence);
}
} }
} }
} }
...@@ -1243,6 +1274,8 @@ public class RayoComponent extends AbstractComponent ...@@ -1243,6 +1274,8 @@ public class RayoComponent extends AbstractComponent
private void finishCallRecord(CallParticipant cp) private void finishCallRecord(CallParticipant cp)
{ {
Log.info( "RayoComponent finishCallRecord " + cp.getStartTimestamp());
if (cp.getStartTimestamp() > 0) if (cp.getStartTimestamp() > 0)
{ {
cp.setEndTimestamp(System.currentTimeMillis()); cp.setEndTimestamp(System.currentTimeMillis());
...@@ -1251,56 +1284,52 @@ public class RayoComponent extends AbstractComponent ...@@ -1251,56 +1284,52 @@ public class RayoComponent extends AbstractComponent
try { try {
ConferenceManager conferenceManager = ConferenceManager.findConferenceManager(cp.getConferenceId()); ConferenceManager conferenceManager = ConferenceManager.findConferenceManager(cp.getConferenceId());
conferenceManager.recordConference(false, null, null); conferenceManager.recordConference(false, null, null);
} catch (Exception e) {}
cp.setStartTimestamp(0); String target = cp.getCallOwner();
} JID destination = getJID(conferenceManager.getCallId());
}
if (destination == null)
{
destination = new JID(conferenceManager.getCallId() + "@" + getDomain());
}
public void initiated(String name, String callId) if (target == null)
{ {
Log.info( "RayoComponent initiated " + name + " " + callId); if (cp.getHandset() != null)
{
target = cp.getHandset().getCallOwner();
}
}
Presence presence = new Presence(); if (target != null)
presence.setFrom(callId + "@rayo." + getDomain()); {
presence.setTo(new JID(name)); try {
presence.getElement().add(rayoProvider.toXML(new RingingEvent(null, null))); sendMessage(new JID(target), destination, "Call ended", null);
sendPacket(presence); } catch (Exception e) {
} e.printStackTrace();
}
}
public void established(String name, String callId) } catch (Exception e) {}
{
Log.info( "RayoComponent established " + name + " " + callId);
Presence presence = new Presence(); cp.setStartTimestamp(0);
presence.setFrom(callId + "@rayo." + getDomain()); }
presence.setTo(new JID(name));
presence.getElement().add(rayoProvider.toXML(new AnsweredEvent(null, null)));
sendPacket(presence);
} }
public void failed(String name, String callId)
{
Log.info( "RayoComponent failed " + name + " " + callId);
Presence presence = new Presence();
presence.setFrom(callId + "@rayo." + getDomain());
presence.setTo(new JID(name));
presence.getElement().add(rayoProvider.toXML(new EndEvent(null, EndEvent.Reason.valueOf("ERROR"), null)));
//sendPacket(presence);
}
public void terminated(String name, String callId) private void sendMessage(JID from, JID to, String body, String fileName)
{ {
Log.info( "RayoComponent terminated " + name + " " + callId); Log.info( "RayoComponent sendMessage " + from + " " + to + " " + body + " " + fileName);
Presence presence = new Presence(); int port = HttpBindManager.getInstance().getHttpBindUnsecurePort();
presence.setFrom(callId + "@rayo." + getDomain()); Message packet = new Message();
presence.setTo(new JID(name)); packet.setTo(to);
presence.getElement().add(rayoProvider.toXML(new EndEvent(null, EndEvent.Reason.valueOf("HANGUP"), null))); packet.setFrom(from);
//sendPacket(presence); packet.setType(Message.Type.chat);
} packet.setThread("http://" + getDomain() + ":" + port + "/rayo/recordings/" + fileName);
packet.setBody(body);
sendPacket(packet);
}
public void sendPacket(Packet packet) public void sendPacket(Packet packet)
{ {
...@@ -1325,7 +1354,7 @@ public class RayoComponent extends AbstractComponent ...@@ -1325,7 +1354,7 @@ public class RayoComponent extends AbstractComponent
ConferenceManager conferenceManager = ConferenceManager.findConferenceManager(conferenceEvent.getConferenceId()); ConferenceManager conferenceManager = ConferenceManager.findConferenceManager(conferenceEvent.getConferenceId());
String groupName = conferenceManager.getDisplayName(); String groupName = conferenceManager.getGroupName();
String callId = conferenceManager.getCallId(); String callId = conferenceManager.getCallId();
if (callId == null) callId = conferenceEvent.getConferenceId(); // special case of SIP incoming if (callId == null) callId = conferenceEvent.getConferenceId(); // special case of SIP incoming
...@@ -1343,11 +1372,9 @@ public class RayoComponent extends AbstractComponent ...@@ -1343,11 +1372,9 @@ public class RayoComponent extends AbstractComponent
{ {
ArrayList memberList = conferenceManager.getMemberList(); ArrayList memberList = conferenceManager.getMemberList();
if (conferenceEvent.equals(ConferenceEvent.MEMBER_LEFT)) if (conferenceEvent.equals(ConferenceEvent.MEMBER_LEFT) && callId.equals(conferenceEvent.getCallId()))
{ {
CallParticipant hp = callParticipant.getHandset(); if (farParty != null && farParty.getCallParticipant().isHeld() == false) // far party left
if (hp != null) // far party left
{ {
synchronized (memberList) synchronized (memberList)
{ {
...@@ -1419,6 +1446,8 @@ public class RayoComponent extends AbstractComponent ...@@ -1419,6 +1446,8 @@ public class RayoComponent extends AbstractComponent
if (memberCount > 2) // conferencing state if (memberCount > 2) // conferencing state
{ {
Log.info( "RayoComponent routeJoinEvent conferenced state " + memberCount);
if (conferenceEvent.equals(ConferenceEvent.MEMBER_LEFT)) if (conferenceEvent.equals(ConferenceEvent.MEMBER_LEFT))
{ {
UnjoinedEvent event = new UnjoinedEvent(null, conferenceEvent.getConferenceId(), JoinDestinationType.MIXER); UnjoinedEvent event = new UnjoinedEvent(null, conferenceEvent.getConferenceId(), JoinDestinationType.MIXER);
...@@ -1435,38 +1464,63 @@ public class RayoComponent extends AbstractComponent ...@@ -1435,38 +1464,63 @@ public class RayoComponent extends AbstractComponent
if (memberCount == 2) // caller with callee only if (memberCount == 2) // caller with callee only
{ {
Log.info( "RayoComponent routeJoinEvent answered state " + callId + " " + conferenceEvent.getCallId());
if (conferenceEvent.equals(ConferenceEvent.MEMBER_LEFT)) // previously conferenced if (conferenceEvent.equals(ConferenceEvent.MEMBER_LEFT)) // previously conferenced
{ {
Log.info( "RayoComponent routeJoinEvent someone left ");
if (callId.equals(conferenceEvent.getCallId()) == false) // handset leaving if (callId.equals(conferenceEvent.getCallId()) == false) // handset leaving
{ {
Log.info( "RayoComponent routeJoinEvent handset leaving ");
presence.getElement().add(rayoProvider.toXML(new AnsweredEvent(null, headers))); presence.getElement().add(rayoProvider.toXML(new AnsweredEvent(null, headers)));
sendPacket(presence); sendPacket(presence);
} else {
Log.info( "RayoComponent routeJoinEvent far party leaving ");
} }
} else { } else {
Log.info( "RayoComponent routeJoinEvent someone joined ");
if (callId.equals(conferenceEvent.getCallId())) // far party joined if (callId.equals(conferenceEvent.getCallId())) // far party joined
{ {
Log.info( "RayoComponent routeJoinEvent far party joined ");
presence.getElement().add(rayoProvider.toXML(new AnsweredEvent(null, headers))); presence.getElement().add(rayoProvider.toXML(new AnsweredEvent(null, headers)));
sendPacket(presence);
} else { // handset joined } else { // handset joined
Log.info( "RayoComponent routeJoinEvent handset joined ");
if (farParty != null) if (farParty != null)
{ {
CallParticipant fp = farParty.getCallParticipant(); CallParticipant fp = farParty.getCallParticipant();
if (fp.isHeld()) if (fp.isHeld())
{ {
Log.info( "RayoComponent routeJoinEvent on hold ");
fp.setHeld(false); fp.setHeld(false);
presence.getElement().add(rayoProvider.toXML(new AnsweredEvent(null, headers))); presence.getElement().add(rayoProvider.toXML(new AnsweredEvent(null, headers)));
sendPacket(presence);
} else { } else {
presence.getElement().add(rayoProvider.toXML(new AnsweredEvent(null, headers))); Log.info( "RayoComponent routeJoinEvent not held " + fp.getProtocol() + " " + fp);
if ("WebRtc".equals(fp.getProtocol()) == false)
{
Log.info( "RayoComponent routeJoinEvent handset joing sip call");
presence.getElement().add(rayoProvider.toXML(new AnsweredEvent(null, headers)));
sendPacket(presence);
}
} }
} }
} }
sendPacket(presence);
} }
} else if (memberCount == 1) { // callee or caller } else if (memberCount == 1) { // callee or caller
...@@ -1478,20 +1532,36 @@ public class RayoComponent extends AbstractComponent ...@@ -1478,20 +1532,36 @@ public class RayoComponent extends AbstractComponent
if (farParty != null) if (farParty != null)
{ {
CallParticipant fp = farParty.getCallParticipant(); CallParticipant fp = farParty.getCallParticipant();
fp.setHeld(true);
presence.getElement().add(toXML(new OnHoldEvent())); if (fp.isHeld())
{
presence.getElement().add(handsetProvider.toXML(new OnHoldEvent()));
sendPacket(presence);
}
}
} else { // far party leaving
if (callParticipant.isHeld())
{
presence.getElement().add(handsetProvider.toXML(new OnHoldEvent()));
sendPacket(presence);
} else {
finishCallRecord(callParticipant);
presence.getElement().add(rayoProvider.toXML(new EndEvent(null, EndEvent.Reason.valueOf("HANGUP"), headers)));
sendPacket(presence); sendPacket(presence);
} }
} }
} }
} else { // nobody left, call ended } else { // nobody left, call ended, signal last handset
presence.getElement().add(rayoProvider.toXML(new EndEvent(null, EndEvent.Reason.valueOf("HANGUP"), headers))); presence.getElement().add(rayoProvider.toXML(new EndEvent(null, EndEvent.Reason.valueOf("HANGUP"), headers)));
sendPacket(presence); sendPacket(presence);
finishCallRecord(callParticipant); //finishCallRecord(callParticipant);
} }
} }
} }
...@@ -1531,7 +1601,7 @@ public class RayoComponent extends AbstractComponent ...@@ -1531,7 +1601,7 @@ public class RayoComponent extends AbstractComponent
cp.setCallId(callId); cp.setCallId(callId);
cp.setMediaPreference("PCMU/8000/1"); cp.setMediaPreference("PCMU/8000/1");
cp.setConferenceId(callId); cp.setConferenceId(callId);
cp.setConferenceDisplayName(cp.getToPhoneNumber());
ConferenceManager conferenceManager = ConferenceManager.getConference(callId, cp.getMediaPreference(), cp.getToPhoneNumber(), false); ConferenceManager conferenceManager = ConferenceManager.getConference(callId, cp.getMediaPreference(), cp.getToPhoneNumber(), false);
conferenceManager.setCallId(callId); conferenceManager.setCallId(callId);
...@@ -1551,6 +1621,8 @@ public class RayoComponent extends AbstractComponent ...@@ -1551,6 +1621,8 @@ public class RayoComponent extends AbstractComponent
try { try {
Group group = GroupManager.getInstance().getGroup(cp.getToPhoneNumber()); Group group = GroupManager.getInstance().getGroup(cp.getToPhoneNumber());
conferenceManager.setGroupName(cp.getToPhoneNumber());
for (JID memberJID : group.getMembers()) for (JID memberJID : group.getMembers())
{ {
Collection<ClientSession> sessions = SessionManager.getInstance().getSessions(memberJID.getNode()); Collection<ClientSession> sessions = SessionManager.getInstance().getSessions(memberJID.getNode());
...@@ -1614,55 +1686,61 @@ public class RayoComponent extends AbstractComponent ...@@ -1614,55 +1686,61 @@ public class RayoComponent extends AbstractComponent
} }
} }
private Element toXML(Object object) private IQHandler onHookIQHandler = null;
{ private IQHandler offHookIQHandler = null;
try { private IQHandler dialIQHandler = null;
Document document = DocumentHelper.createDocument(); private IQHandler hangupIQHandler = null;
generateDocument(object, document);
return document.getRootElement();
} catch (Exception e) {
throw new IllegalStateException(e);
}
}
private void generateDocument(Object object, Document document) throws Exception private void createIQHandlers()
{ {
if (object instanceof OnHoldEvent) { XMPPServer server = XMPPServer.getInstance();
createOnHoldEvent((OnHoldEvent) object, document);
} else if (object instanceof OffHoldEvent) { onHookIQHandler = new OnHookIQHandler(); server.getIQRouter().addHandler(onHookIQHandler);
createOffHoldEvent((OffHoldEvent) object, document); offHookIQHandler = new OffHookIQHandler(); server.getIQRouter().addHandler(offHookIQHandler);
dialIQHandler = new DialIQHandler(); server.getIQRouter().addHandler(dialIQHandler);
hangupIQHandler = new HangupIQHandler(); server.getIQRouter().addHandler(hangupIQHandler);
}
} else if (object instanceof MutedEvent) { private void destroyIQHandlers()
createMutedEvent((MutedEvent) object, document); {
XMPPServer server = XMPPServer.getInstance();
} else if (object instanceof UnmutedEvent) { if (onHookIQHandler != null) {server.getIQRouter().removeHandler(onHookIQHandler); onHookIQHandler = null;}
createUnmutedEvent((UnmutedEvent) object, document); if (offHookIQHandler != null) {server.getIQRouter().removeHandler(offHookIQHandler); offHookIQHandler = null;}
} if (dialIQHandler != null) {server.getIQRouter().removeHandler(dialIQHandler); dialIQHandler = null;}
} if (hangupIQHandler != null) {server.getIQRouter().removeHandler(hangupIQHandler); hangupIQHandler = null;}
}
private Document createOnHoldEvent(OnHoldEvent onHold, Document document) private class OnHookIQHandler extends IQHandler
{ {
Element root = document.addElement(new QName("onhold", new Namespace("", "urn:xmpp:rayo:1"))); public OnHookIQHandler() { super("Rayo: XEP 0327 - Onhook");}
return document;
@Override public IQ handleIQ(IQ iq) {try {return handleIQGet(iq);} catch(Exception e) {return null;} }
@Override public IQHandlerInfo getInfo() { return new IQHandlerInfo("onhook", RAYO_HANDSET); }
} }
private Document createOffHoldEvent(OffHoldEvent offHold, Document document) private class OffHookIQHandler extends IQHandler
{ {
Element root = document.addElement(new QName("offhold", new Namespace("", "urn:xmpp:rayo:1"))); public OffHookIQHandler() { super("Rayo: XEP 0327 - Offhook");}
return document;
@Override public IQ handleIQ(IQ iq) {try {return handleIQGet(iq);} catch(Exception e) { return null;}}
@Override public IQHandlerInfo getInfo() { return new IQHandlerInfo("offhook", RAYO_HANDSET); }
} }
private Document createMutedEvent(MutedEvent muted, Document document) private class DialIQHandler extends IQHandler
{ {
Element root = document.addElement(new QName("onmute", new Namespace("", "urn:xmpp:rayo:1"))); public DialIQHandler() { super("Rayo: XEP 0327 - Dial");}
return document;
@Override public IQ handleIQ(IQ iq) {try {return handleIQGet(iq);} catch(Exception e) { return null;}}
@Override public IQHandlerInfo getInfo() { return new IQHandlerInfo("dial", RAYO_CORE); }
} }
private Document createUnmutedEvent(UnmutedEvent unmuted, Document document) private class HangupIQHandler extends IQHandler
{ {
Element root = document.addElement(new QName("offmute", new Namespace("", "urn:xmpp:rayo:1"))); public HangupIQHandler() { super("Rayo: XEP 0327 - Hangup");}
return document;
@Override public IQ handleIQ(IQ iq) {try {return handleIQGet(iq);} catch(Exception e) { return null;}}
@Override public IQHandlerInfo getInfo() { return new IQHandlerInfo("hangup", RAYO_CORE); }
} }
} }
...@@ -104,6 +104,8 @@ public class RayoPlugin implements Plugin, SessionEventListener { ...@@ -104,6 +104,8 @@ public class RayoPlugin implements Plugin, SessionEventListener {
Log.error("Could NOT load " + component.getName()); Log.error("Could NOT load " + component.getName());
} }
setup(); setup();
component.doStart();
} }
private void setup() { private void setup() {
...@@ -191,6 +193,7 @@ public class RayoPlugin implements Plugin, SessionEventListener { ...@@ -191,6 +193,7 @@ public class RayoPlugin implements Plugin, SessionEventListener {
} }
closeAllChannels(); closeAllChannels();
executor.shutdownNow(); executor.shutdownNow();
component.doStop();
} }
public boolean hasPublicIP() { public boolean hasPublicIP() {
......
...@@ -54,13 +54,13 @@ Strophe.addConnectionPlugin('rayo', ...@@ -54,13 +54,13 @@ Strophe.addConnectionPlugin('rayo',
//console.log("hangup " + callId); //console.log("hangup " + callId);
var that = this; var that = this;
var iq = $iq({to: callId + "@rayo." + this._connection.domain, from: this._connection.jid, type: "get"}).c("hangup", {xmlns: Strophe.NS.RAYO_CORE}); var iq = $iq({to: callId + "@" + this._connection.domain, from: this._connection.jid, type: "get"}).c("hangup", {xmlns: Strophe.NS.RAYO_CORE});
//console.log(iq.toString()); //console.log(iq.toString());
that._connection.sendIQ(iq, function() that._connection.sendIQ(iq, function()
{ {
this._onhook(); that._onhook();
}, function(error) { }, function(error) {
...@@ -108,13 +108,98 @@ Strophe.addConnectionPlugin('rayo', ...@@ -108,13 +108,98 @@ Strophe.addConnectionPlugin('rayo',
this._onhook(); this._onhook();
}, },
hold: function(callId)
{
//console.log("hold " + callId);
var that = this;
var iq = $iq({to: callId + "@rayo." + this._connection.domain, from: this._connection.jid, type: "get"}).c("hold", {xmlns: Strophe.NS.RAYO_HANDSET});
//console.log(iq.toString());
that._connection.sendIQ(iq, function()
{
that._onhook();
}, function(error) {
//console.log(error);
$('error', error).each(function()
{
var errorcode = $(this).attr('code');
if (that.callbacks && that.callbacks.onError) that.callbacks.onError("hold failure " + errorcode);
});
});
},
redirect: function(to, mixer, headers)
{
//console.log("redirect " + to + " " + mixer);
var that = this;
var iq = $iq({to: callId + "@rayo." + this._connection.domain, from: this._connection.jid, type: "get"}).c("redirect", {xmlns: Strophe.NS.RAYO_CORE, to: to});
if (headers)
{
var hdrs = Object.getOwnPropertyNames(headers)
for (var i=0; i< hdrs.length; i++)
{
var name = hdrs[i];
var value = headers[name];
if (value) iq.c("header", {name: name, value: value}).up();
}
}
console.log(iq.toString());
that._connection.sendIQ(iq, function(response)
{
$('ref', response).each(function()
{
callId = $(this).attr('id');
if (that._isOffhook()) that._onhook();
if (that.callbacks && that.callbacks.onRedirect) that.callbacks.onRedirect(callId);
});
}, function(error) {
console.log(error);
$('error', error).each(function()
{
var errorcode = $(this).attr('code');
if (that.callbacks && that.callbacks.onError) that.callbacks.onError("redirect failure " + errorcode);
});
});
},
private: function(callId, flag)
{
//console.log('Rayo plugin private ' + callId + " " + flag);
var that = this;
var iq = $iq({to: callId + "@rayo." + this._connection.domain, from: this._connection.jid, type: "get"}).c( flag ? "private" : "public", {xmlns: Strophe.NS.RAYO_HANDSET});
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("private/public failure " + errorcode);
});
});
},
mute: function(callId, flag) mute: function(callId, flag)
{ {
//console.log('Rayo plugin mute ' + callId + " " + flag); //console.log('Rayo plugin mute ' + callId + " " + flag);
var that = this; 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}); var iq = $iq({to: callId + "@rayo." + this._connection.domain, from: this._connection.jid, type: "get"}).c( flag ? "mute" : "unmute", {xmlns: Strophe.NS.RAYO_HANDSET});
that._connection.sendIQ(iq, null, function(error) that._connection.sendIQ(iq, null, function(error)
{ {
...@@ -127,32 +212,37 @@ Strophe.addConnectionPlugin('rayo', ...@@ -127,32 +212,37 @@ Strophe.addConnectionPlugin('rayo',
}, },
answer: function(callId, mixer, headers) answer: function(callId, mixer, headers, callFrom)
{ {
//console.log('Rayo plugin accept ' + callId + " " + mixer); //console.log('Rayo plugin accept ' + callId + " " + mixer);
//console.log(headers)
var that = this; var that = this;
if (this._isOffhook()) this._onhook(); if (this._isOffhook()) this._onhook();
if (!headers) headers = {};
headers.call_id = callId;
//console.log(headers)
this._offhook(mixer, headers, function() this._offhook(mixer, headers, function()
{ {
var iq = $iq({to: callId + "@rayo." + that._connection.domain, from: that._connection.jid, type: "get"}).c("answer", {xmlns: Strophe.NS.RAYO_CORE}); var iq = $iq({to: callId + "@rayo." + that._connection.domain, from: that._connection.jid, type: "get"}).c("answer", {xmlns: Strophe.NS.RAYO_CORE});
var hdrs = Object.getOwnPropertyNames(headers)
if (headers) for (var i=0; i< hdrs.length; i++)
{ {
var hdrs = Object.getOwnPropertyNames(headers) var name = hdrs[i];
var value = headers[name];
for (var i=0; i< hdrs.length; i++)
{
var name = hdrs[i];
var value = headers[name];
if (value) iq.c("header", {name: name, value: value}).up(); if (value) iq.c("header", {name: name, value: value}).up();
}
} }
iq.c("header", {name: "caller_id", value: callFrom}).up();
iq.c("header", {name: "mixer_name", value: mixer}).up();
//console.log(iq.toString()); //console.log(iq.toString());
that._connection.sendIQ(iq, null, function(error) that._connection.sendIQ(iq, null, function(error)
...@@ -176,11 +266,11 @@ Strophe.addConnectionPlugin('rayo', ...@@ -176,11 +266,11 @@ Strophe.addConnectionPlugin('rayo',
var mixer = "rayo-outgoing-" + Math.random().toString(36).substr(2,9); var mixer = "rayo-outgoing-" + Math.random().toString(36).substr(2,9);
if (this._isOffhook()) this._onhook(); if (this._isOffhook()) this._onhook();
this._offhook(mixer, headers, function() this._offhook(mixer, headers, function()
{ {
var iq = $iq({to: "rayo." + 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)
{ {
...@@ -207,15 +297,19 @@ Strophe.addConnectionPlugin('rayo', ...@@ -207,15 +297,19 @@ Strophe.addConnectionPlugin('rayo',
{ {
that.callbacks.onAccept( that.callbacks.onAccept(
{ {
digit: function(tone) {that.digit(callId, tone);}, digit: function(tone) {that.digit(callId, tone);},
hangup: function() {that.hangup(callId);}, redirect: function(to) {that.redirect(to, mixer, headers);},
join: function() {that.join(mixer, headers);}, hangup: function() {that.hangup(callId);},
leave: function() {that.leave(mixer);}, hold: function() {that.hold(callId);},
mute: function(flag) {that.mute(callId, flag);}, join: function() {that.join(mixer, headers);},
leave: function() {that.leave(mixer);},
mute: function(flag) {that.mute(callId, flag);},
private: function() {that.private(callId, !this.privateCall);},
from: from, from: from,
to: to, to: to,
id: callId id: callId,
privateCall: false
}); });
} }
}); });
...@@ -256,7 +350,7 @@ Strophe.addConnectionPlugin('rayo', ...@@ -256,7 +350,7 @@ Strophe.addConnectionPlugin('rayo',
var codec = (headers && headers.codec_name) ? headers.codec_name : (that.callbacks.codec_name ? that.callbacks.codec_name : "OPUS"); var codec = (headers && headers.codec_name) ? headers.codec_name : (that.callbacks.codec_name ? that.callbacks.codec_name : "OPUS");
var iq = $iq({to: "rayo." + that._connection.domain, from: that._connection.jid, type: "get"}).c("offhook", {xmlns: Strophe.NS.RAYO_HANDSET, sipuri: sipuri, mixer: mixer, group: group, codec: codec}); var iq = $iq({to: that._connection.domain, from: that._connection.jid, type: "get"}).c("offhook", {xmlns: Strophe.NS.RAYO_HANDSET, sipuri: sipuri, mixer: mixer, group: group, codec: codec});
//console.log(iq.toString()) //console.log(iq.toString())
...@@ -352,8 +446,9 @@ Strophe.addConnectionPlugin('rayo', ...@@ -352,8 +446,9 @@ Strophe.addConnectionPlugin('rayo',
var stereo = (headers && headers.stereo_pan) ? headers.stereo_pan : (that.callbacks.stereo_pan ? that.callbacks.stereo_pan : "0"); var stereo = (headers && headers.stereo_pan) ? headers.stereo_pan : (that.callbacks.stereo_pan ? that.callbacks.stereo_pan : "0");
var codec = (headers && headers.codec_name) ? headers.codec_name : (that.callbacks.codec_name ? that.callbacks.codec_name : "OPUS"); var codec = (headers && headers.codec_name) ? headers.codec_name : (that.callbacks.codec_name ? that.callbacks.codec_name : "OPUS");
var group = (headers && headers.group_name) ? headers.group_name : ""; var group = (headers && headers.group_name) ? headers.group_name : "";
var callid = (headers && headers.call_id) ? headers.call_id : "";
var iq = $iq({to: "rayo." + that._connection.domain, from: that._connection.jid, type: "get"}).c("offhook", {xmlns: Strophe.NS.RAYO_HANDSET, cryptoSuite: that.cryptoSuite, localCrypto: that.localCrypto, remoteCrypto: that.remoteCrypto, codec: codec, stereo: stereo, mixer: mixer, group: group}); var iq = $iq({to: that._connection.domain, from: that._connection.jid, type: "get"}).c("offhook", {xmlns: Strophe.NS.RAYO_HANDSET, cryptoSuite: that.cryptoSuite, localCrypto: that.localCrypto, remoteCrypto: that.remoteCrypto, codec: codec, stereo: stereo, mixer: mixer, group: group, callid: callid});
//console.log(iq.toString()) //console.log(iq.toString())
...@@ -384,7 +479,7 @@ Strophe.addConnectionPlugin('rayo', ...@@ -384,7 +479,7 @@ Strophe.addConnectionPlugin('rayo',
//console.log('Rayo plugin onhook ' + this.handsetId); //console.log('Rayo plugin onhook ' + this.handsetId);
that = this; that = this;
var server = this.handsetId + "@rayo." + this._connection.domain; var server = this.handsetId + "@" + this._connection.domain;
this._connection.sendIQ($iq({to: server, from: this._connection.jid, type: "get"}).c('onhook', {xmlns: Strophe.NS.RAYO_HANDSET}), function(response) this._connection.sendIQ($iq({to: server, from: this._connection.jid, type: "get"}).c('onhook', {xmlns: Strophe.NS.RAYO_HANDSET}), function(response)
{ {
...@@ -440,16 +535,20 @@ Strophe.addConnectionPlugin('rayo', ...@@ -440,16 +535,20 @@ Strophe.addConnectionPlugin('rayo',
var mixer = headers.mixer_name; var mixer = headers.mixer_name;
var call = { var call = {
digit: function(tone) {that.digit(callId, tone);}, digit: function(tone) {that.digit(callId, tone);},
hangup: function() {that.hangup(callId);}, redirect: function(to) {that.redirect(to, mixer, headers);},
answer: function() {that.answer(callId, mixer, headers);}, hangup: function() {that.hangup(callId);},
join: function() {that.join(mixer, headers);}, hold: function() {that.hold(callId);},
leave: function() {that.leave(mixer);}, answer: function() {that.answer(callId, mixer, headers, callFrom);},
mute: function(flag) {that.mute(callId, flag);}, join: function() {that.join(mixer, headers);},
leave: function() {that.leave(mixer);},
mute: function(flag) {that.mute(callId, flag);},
private: function() {that.private(callId, !this.privateCall);},
from: callFrom, from: callFrom,
to: callTo, to: callTo,
id: callId id: callId,
privateCall: false
} }
if (that.callbacks && that.callbacks.onOffer) that.callbacks.onOffer(call, headers); if (that.callbacks && that.callbacks.onOffer) that.callbacks.onOffer(call, headers);
...@@ -466,6 +565,9 @@ Strophe.addConnectionPlugin('rayo', ...@@ -466,6 +565,9 @@ Strophe.addConnectionPlugin('rayo',
if (value) iq.c("header", {name: name, value: value}).up(); if (value) iq.c("header", {name: name, value: value}).up();
} }
iq.c("header", {name: "caller_id", value: callFrom}).up();
iq.c("header", {name: "mixer_name", value: mixer}).up();
//console.log(iq.toString()); //console.log(iq.toString());
that._connection.sendIQ(iq, null, function(error) that._connection.sendIQ(iq, null, function(error)
...@@ -543,7 +645,7 @@ Strophe.addConnectionPlugin('rayo', ...@@ -543,7 +645,7 @@ Strophe.addConnectionPlugin('rayo',
{ {
//console.log(presence); //console.log(presence);
if ($(this).attr('xmlns') == Strophe.NS.RAYO_CORE) if ($(this).attr('xmlns') == Strophe.NS.RAYO_HANDSET)
{ {
var callId = Strophe.getNodeFromJid(from); var callId = Strophe.getNodeFromJid(from);
if (that.callbacks && that.callbacks.onHold) that.callbacks.onHold(callId); if (that.callbacks && that.callbacks.onHold) that.callbacks.onHold(callId);
...@@ -554,7 +656,7 @@ Strophe.addConnectionPlugin('rayo', ...@@ -554,7 +656,7 @@ Strophe.addConnectionPlugin('rayo',
{ {
//console.log(presence); //console.log(presence);
if ($(this).attr('xmlns') == Strophe.NS.RAYO_CORE) if ($(this).attr('xmlns') == Strophe.NS.RAYO_HANDSET)
{ {
var callId = Strophe.getNodeFromJid(from); var callId = Strophe.getNodeFromJid(from);
if (that.callbacks && that.callbacks.onMute) that.callbacks.onMute(callId); if (that.callbacks && that.callbacks.onMute) that.callbacks.onMute(callId);
...@@ -565,15 +667,39 @@ Strophe.addConnectionPlugin('rayo', ...@@ -565,15 +667,39 @@ Strophe.addConnectionPlugin('rayo',
{ {
//console.log(presence); //console.log(presence);
if ($(this).attr('xmlns') == Strophe.NS.RAYO_CORE) if ($(this).attr('xmlns') == Strophe.NS.RAYO_HANDSET)
{ {
var callId = Strophe.getNodeFromJid(from); var callId = Strophe.getNodeFromJid(from);
if (that.callbacks && that.callbacks.offMute) that.callbacks.offMute(callId); if (that.callbacks && that.callbacks.offMute) that.callbacks.offMute(callId);
} }
});
$(presence).find('private').each(function()
{
//console.log(presence);
if ($(this).attr('xmlns') == Strophe.NS.RAYO_HANDSET)
{
var callId = Strophe.getNodeFromJid(from);
if (that.callbacks && that.callbacks.onPrivate) that.callbacks.onPrivate(callId);
}
});
$(presence).find('public').each(function()
{
//console.log(presence);
if ($(this).attr('xmlns') == Strophe.NS.RAYO_HANDSET)
{
var callId = Strophe.getNodeFromJid(from);
if (that.callbacks && that.callbacks.offPrivate) that.callbacks.offPrivate(callId);
}
}); });
$(presence).find('ringing').each(function() $(presence).find('ringing').each(function()
{ {
//console.log(presence);
if ($(this).attr('xmlns') == Strophe.NS.RAYO_CORE) if ($(this).attr('xmlns') == Strophe.NS.RAYO_CORE)
{ {
var callId = Strophe.getNodeFromJid(from); var callId = Strophe.getNodeFromJid(from);
...@@ -610,15 +736,17 @@ Strophe.addConnectionPlugin('rayo', ...@@ -610,15 +736,17 @@ Strophe.addConnectionPlugin('rayo',
var mixer = headers.mixer_name; var mixer = headers.mixer_name;
var call = { var call = {
digit: function(tone) {that.digit(callId, tone);}, digit: function(tone) {that.digit(callId, tone);},
hangup: function() {that.hangup(callId);}, hangup: function() {that.hangup(callId);},
answer: function() {that.answer(callId, mixer, headers);}, hold: function() {that.hold(callId);},
join: function() {that.join(mixer, headers);}, join: function() {that.join(mixer, headers);},
leave: function() {that.leave(mixer);}, leave: function() {that.leave(mixer);},
mute: function(flag) {that.mute(callId, flag);}, mute: function(flag) {that.mute(callId, flag);},
private: function() {that.private(callId, !this.privateCall);},
id: callId, id: callId,
from: Strophe.getNodeFromJid(jid) from: Strophe.getNodeFromJid(jid),
privateCall: false
} }
if (that.callbacks && that.callbacks.onHook) that.callbacks.onHook(); if (that.callbacks && that.callbacks.onHook) that.callbacks.onHook();
if (that.callbacks && that.callbacks.onBusy) that.callbacks.onBusy(call, headers); if (that.callbacks && that.callbacks.onBusy) that.callbacks.onBusy(call, headers);
......
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