/**
* @ngdoc directives
* @name Voip
* @module s4c.directives.voip.Voip
*
* @description
* `voipCtrl` Responsável por exibir as funções do voip na tela, bem como o seu funcionamento
* também possui acesso a api do backe
*
*@example
* <s4c-voip>
* </s4c-voip>
*/
(function () {
'use strict';
voipCtrl.$inject = [
'$scope',
'$http',
'$mdDialog',
'$state',
'API_ENDPOINT',
'$q',
'TarefaService',
'MainState',
'CommService',
'AuthService',
'TarefaManager',
'localize',
'CamadasService',
'Base',
'Usuario',
'ParametrosS4C',
'DetalhamentoManager',
'MapaService',
'VoipManager',
'VoipService'
];
/** This is a description of the voip function. */
function voipCtrl($scope, $http, $mdDialog, $state,
API_ENDPOINT, $q, TarefaService, MainState, CommService, AuthService, TarefaManager, localize, CamadasService, Base, Usuario, ParametrosS4C, DetalhamentoManager, MapaService, VoipManager, VoipService) {
$scope.res = $scope.$root.res;
var ringtone_ = document.getElementById("ringtone");
var ringbacktone_ = document.getElementById("ringbacktone");
var audioRemote = document.getElementById("audio_remote");
var audioLocal = document.getElementById("audio_remote");
$("#voip_button").css('opacity', '0.5');
/**
* keybord numeric voip multivis Fusion
*
*@autor - Rafael Araujo
*@param div classPai, textoBtn, input
*/
$scope.numClick = function (classPai, textoBtn, input) {
$('.' + classPai).on('click', function () {
var num = $(this);
var text = $.trim(num.find('.' + textoBtn).clone().children().remove().end().text());
var telNumber = $(input);
$(telNumber).val(telNumber.val() + text);
// $('.campoTel').addClass('md-input-focused')
$('#ramal').focus()
});
};
/**
* Limpar campo
*
*@autor - Rafael Araujo
*@param Input, btnAcao
*/
$scope.limparCampo = function (inputNumero, btnAcao) {
$('.' + btnAcao).on('click', function () {
var telNumber = $(inputNumero);
$(telNumber).val('');
});
};
$scope.numClick('num', 'txt', '[data-set="numero"]');
$scope.limparCampo('[data-set="numero"]', 'limpar');
/**
* @method hangup
* @param {*} ramal_
*/
CommService.on('hangup', function (ramal_) {
if (ramal_ != null && ramal_ == VoipService.usuarioRamal) {
desligar();
}
});
/**
* @method mute
* @param {*} ramal_
*/
CommService.on('mute', function (ramal_) {
if (ramal_ != null && ramal_ == VoipService.usuarioRamal) {
mute();
}
});
/**
* @method readyCallback
* @param {*} e
*/
var readyCallback = function (e) {
if (MainState.isToShow('voip')) {
createSipStack(); // see next section
}
};
/**
* @method errorCallback
* @param {*} e
*/
var errorCallback = function (e) {
console.error('Failed to initialize the engine: ' + e.message);
}
/**
* @method eventsListener
* @param {*} e
*/
var eventsListener = function (e) {
console.info('session event = ' + e.type);
if (e.type == 'started') {
login();
}
else if (e.type == 'i_new_message') { // incoming new SIP MESSAGE (SMS-like)
acceptMessage(e);
}
else if (e.type == 'i_new_call') { // incoming audio/video call
startRingTone();
VoipService.sipSessionCall = e.newSession;
VoipManager.abrir();
$("#making_call").hide();
$("#discador").hide();
$("#dicador").hide();
$("#receiving_call").show();
$("#in_call").hide();
$("#making_call_field").hide();
$("#receiving_call_field").show();
$('#ramal').focus()
setTimeout(function () { $('#ramal').focus(); }, 500);
VoipService.s_user_name = e.o_event.o_message.o_hdr_From.o_uri.s_user_name;
VoipService.displayName = e.o_event.o_message.o_hdr_From.s_display_name;
if (VoipService.displayName == null) {
VoipService.displayName = VoipService.s_user_name;
} else if (VoipService.displayName != null && VoipService.s_user_name != null) {
VoipService.displayName += ", ramal " + VoipService.s_user_name;
}
$("#mensagem").text("Você está recebendo uma ligação do " + VoipService.displayName);
} else if (e.type == 'connected' && e.session == VoipService.registerSession) {
publishPresence();
subscribePresence(VoipService.usuarioRamal); // watch johndoe's presence status change
}
else if (e.type == 'connected' && e.description == 'In Call') {
if ($('#in_call').is(':visible')) {
$("#mensagem").text("A chamada está ativa com o ramal " + VoipService.displayName);
stopRingBackTone();
}
}
else if (e.type == 'i_request_cancel' && e.description == 'Media Removed') {
$("#mensagem").text("A ligação foi encerrada");
stopRingTone();
hangupCall(e);
}
else if (e.type == 'i_notify') {
console.info('NOTIFY content = ' + e.getContentString());
console.info('NOTIFY content-type = ' + e.getContentType());
if (e.getContentType() == 'application/pidf+xml') {
if (window.DOMParser) {
var parser = new DOMParser();
var xmlDoc = parser ? parser.parseFromString(e.getContentString(), "text/xml") : null;
var presenceNode = xmlDoc ? xmlDoc.getElementsByTagName("presence")[0] : null;
if (presenceNode) {
var entityUri = presenceNode.getAttribute("entity");
var tupleNode = presenceNode.getElementsByTagName("tuple")[0];
if (entityUri && tupleNode) {
var statusNode = tupleNode.getElementsByTagName("status")[0];
if (statusNode) {
var basicNode = statusNode.getElementsByTagName("basic")[0];
if (basicNode) {
console.info('Presence notification: Uri = ' + entityUri + ' status = ' + basicNode.textContent);
}
}
}
}
}
}
} else if (e.type == 'terminated' && e.description == 'Call terminated') {
hangupCall(e);
} else if (e.type == 'i_ao_request' && e.description == 'Busy Here') {
stopRingBackTone();
} else if (e.type == 'terminated' && e.description == 'Busy Here') {
hangupCall(e);
} else if (e.type == 'failed_to_start') {
VoipService.isConnecting = false;
$mdDialog.show($mdDialog.alert()
.title($scope.res('COMUM_AVISO'))
.content($scope.res('VOIP_CANNOT_CONECT'))
.ok($scope.res('COMUM_OK')));
$('#voip_button_div').attr('ng-click', '');
$("#voip_button_div").click(function () {
if (!VoipService.isConnecting && !VoipService.isConnected) {
$mdDialog.show($mdDialog.alert()
.title($scope.res('COMUM_AVISO'))
.content($scope.res('VOIP_RETRY_CONECT'))
.ok($scope.res('COMUM_OK')));
createSipStack();
}
});
}
}
/**
* @method createSipStack
*/
function createSipStack() {
Usuario.obterPorId(AuthService.user.info.id).then(function (usuario) {
if (ParametrosS4C.parametros.domainVoip == null || usuario.voipRamal == null || ParametrosS4C.parametros.urlServerVoip == null || usuario.senhaVoipRamal == null) {
VoipService.isSetCorrectly = false;
return;
}
try {
if (ParametrosS4C.parametros.domainVoip != null && ParametrosS4C.parametros.urlServerVoip != null && !VoipService.isConnected && !VoipService.isConnecting) {
VoipService.isConnecting = true;
VoipService.isSetCorrectly = true;
VoipService.usuarioRamal = usuario.voipRamal;
VoipService.sipStack = new SIPml.Stack({
realm: ParametrosS4C.parametros.domainVoip, // mandatory: domain name
impi: usuario.voipRamal, // mandatory: authorization name (IMS Private Identity)
impu: 'sip:' + usuario.voipRamal + '@' + ParametrosS4C.parametros.domainVoip, // mandatory: valid SIP Uri (IMS Public Identity)
password: usuario.senhaVoipRamal, // optional
ice_servers: [], // Array vazio para desabilitar o Stun / turn, quando a rede não tiver um nat.
//display_name: 'Bob legend', // optional
websocket_proxy_url: ParametrosS4C.parametros.urlServerVoip, // optional
// outbound_proxy_url: 'udp://example.org:5060', // optional
//enable_rtcweb_breaker: false, // optional
events_listener: { events: '*', listener: eventsListener }, // optional: '*' means all events
sip_headers: [ // optional
{ name: 'User-Agent', value: 'IM-client/OMA1.0 sipML5-v1.0.0.0' },
{ name: 'Organization', value: 'Doubango Telecom' }
]
});
VoipService.sipStack.start();
}
} catch (Err) {
$mdDialog.show($mdDialog.alert()
.title($scope.res('COMUM_AVISO'))
.content($scope.res('VOIP_CANNOT_CONECT'))
.ok($scope.res('COMUM_OK')));
}
});
}
/**
* @method login
*/
var login = function () {
if (VoipService.sipStack == null) {
_verfiyConfig();
return;
}
VoipService.registerSession = VoipService.sipStack.newSession('register', {
events_listener: { events: '*', listener: eventsListener } // optional: '*' means all events
});
//VoipService.registerSession.unregister();
VoipService.registerSession.register();
}
/**
* @method makeCall
* @param {*} callid
*/
var makeCall = function (callid) {
if (VoipService.sipStack == null) {
_verfiyConfig();
return;
}
VoipService.sipSessionCall = VoipService.sipStack.newSession('call-audio', VoipService.oConfigMakeCall);
VoipService.sipSessionCall.call(callid);
startRingBackTone();
}
/**
* @method acceptCall
*/
var acceptCall = function () {
VoipService.sipSessionCall.accept(VoipService.oConfigMakeCall);
}
/**
* @method rejectCall
*/
var rejectCall = function () {
VoipService.displayName = '';
VoipService.sipSessionCall.reject(VoipService.oConfigMakeCall); // e.newSession.reject() to reject the call
}
/**
* @method hangupCall
* @param {*} e
*/
var hangupCall = function (e) {
if (VoipService.sipStack == null) {
_verfiyConfig();
return;
}
if (e.session != null) {
e.session.hangup({
events_listener: { events: '*', listener: eventsListener } // optional: '*' means all events
}); // e.newSession.reject() to reject the call
}
//publishPresence();
//subscribePresence(VoipService.usuarioRamal);
$("#making_call").show();
$("#discador").show();
$("#receiving_call").hide();
$("#in_call").hide();
$("#making_call_field").show();
$("#receiving_call_field").hide();
stopRingBackTone();
VoipService.displayName = '';
VoipService.b_mute = false;
$("#mute").show();
$("#sound").hide();
}
/**
* @method sendMessage
*/
var sendMessage = function () {
if (VoipService.sipStack == null) {
_verfiyConfig();
return;
}
VoipService.messageSession = VoipService.sipStack.newSession('message', {
events_listener: { events: '*', listener: eventsListener } // optional: '*' means all events
});
// VoipService.messageSession.send('johndoe', 'Pêche à la moule', 'text/plain;charset=utf-8');
}
/**
* @method acceptMessage
* @param {*} e
*/
var acceptMessage = function (e) {
if (VoipService.sipStack == null) {
_verfiyConfig();
return;
}
e.newSession.accept(); // e.newSession.reject(); to reject the message
$mdDialog.show($mdDialog.alert()
.title('SMS received')
.content(e.getContentString())
.ok($scope.res('COMUM_OK')));
console.info('SMS-content = ' + e.getContentString() + ' and SMS-content-type = ' + e.getContentType());
}
/**
* @method publishPresence
*/
var publishPresence = function () {
if (VoipService.sipStack == null) {
_verfiyConfig();
return;
}
VoipService.publishSession = VoipService.sipStack.newSession('publish', {
events_listener: { events: '*', listener: eventsListener } // optional: '*' means all events
});
var contentType = 'application/pidf+xml';
var content = '<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n' +
'<presence xmlns=\"urn:ietf:params:xml:ns:pidf\"\n' +
' xmlns:im=\"urn:ietf:params:xml:ns:pidf:im\"' +
' entity=\"sip:bob@example.com\">\n' +
'<tuple id=\"s8794\">\n' +
'<status>\n' +
' <basic>open</basic>\n' +
' <im:im>away</im:im>\n' +
'</status>\n' +
'<contact priority=\"0.8\">tel:+33600000000</contact>\n' +
'<note xml:lang=\"fr\">Bonjour de Paris :)</note>\n' +
'</tuple>\n' +
'</presence>';
// send the PUBLISH request
VoipService.publishSession.publish(content, contentType, {
expires: 200,
sip_caps: [
{ name: '+g.oma.sip-im' },
{ name: '+sip.ice' },
{ name: 'language', value: '\"en,fr\"' }
],
sip_headers: [
{ name: 'Event', value: 'presence' },
{ name: 'Organization', value: 'Doubango Telecom' }
]
});
}
/**
* @method subscribePresence
* @param {*} to
*/
var subscribePresence = function (to) {
if (VoipService.sipStack == null) {
_verfiyConfig();
return;
}
VoipService.subscribeSession = VoipService.sipStack.newSession('subscribe', {
expires: 200,
events_listener: { events: '*', listener: eventsListener },
sip_headers: [
{ name: 'Event', value: 'presence' }, // only notify for 'presence' events
{ name: 'Accept', value: 'application/pidf+xml' } // supported content types (COMMA-sparated)
],
sip_caps: [
{ name: '+g.oma.sip-im', value: null },
{ name: '+audio', value: null },
{ name: 'language', value: '\"en,fr\"' }
]
});
// start watching for entity's presence status (You may track event type 'connected' to be sure that the request has been accepted by the server)
//subscribeSession.unsubscribe();
VoipService.subscribeSession.subscribe(to);
VoipService.isConnected = true;
VoipService.isConnecting = false;
$("#voip_button").css('opacity', '1');
}
/**
* @method startTalking
*/
function startTalking() {
try { audioRemote.play(); }
catch (e) { }
}
/**
* @method stopTalking
*/
function stopTalking() {
try { audioRemote.stop(); }
catch (e) { }
}
/**
* @method startRingTone
*/
function startRingTone() {
try { ringtone_.play(); }
catch (e) { }
}
/**
* @method stopRingTone
*/
function stopRingTone() {
try { ringtone_.pause(); }
catch (e) { }
}
/**
* @method startRingBackTone
*/
function startRingBackTone() {
try { ringbacktone_.play(); }
catch (e) { }
}
/**
* @method stopRingBackTone
*
*/
function stopRingBackTone() {
try { ringbacktone_.pause(); }
catch (e) { }
}
/**
* Definição do Objeto oConfigMakeCall
* @instance oConfigMakeCall
*/
VoipService.oConfigMakeCall = {
from: VoipService.usuarioRamal,
audio_remote: audioRemote,
//audio_local: audioLocal,
events_listener: { events: '*', listener: eventsListener },
sip_caps: [
{ name: '+g.oma.sip-im' },
{ name: 'language', value: '\"en,fr\"' }
]
};
/**
* @method _verfiyConfig
*/
function _verfiyConfig() {
$mdDialog.show($mdDialog.alert()
.title($scope.res('COMUM_AVISO'))
.content($scope.res('CHECK_VOIP_CONFIG'))
.ok($scope.res('COMUM_OK')));
}
/**
* @method ligar
* @param {*} ramal_
*/
function ligar(ramal_) {
if (VoipService.sipStack == null) {
_verfiyConfig();
return;
}
var ramal = null;
if (ramal_ != null && ramal_ != "") {
ramal = ramal_;
} else if ($("#ramal").val() != null && $("#ramal").val() != "") {
ramal = $("#ramal").val();
}
if (ramal != null) {
makeCall(ramal);
$("#making_call").hide();
$("#discador").hide();
$("#receiving_call").hide();
$("#in_call").show();
$("#making_call_field").hide();
$("#receiving_call_field").show();
$("#mensagem").text("Você está ligando para o ramal " + ramal);
$("#ramal").val("");
VoipService.displayName = ramal;
Base.obter('pois/ramal/' + ramal).then(function (pois) {
if (pois != null && pois.length > 0) {
var latlng = {
lat: pois[0].latitude,
lng: pois[0].longitude
};
if (!DetalhamentoManager.samePoi(pois[0].id)) {
DetalhamentoManager.abrirPoi(pois[0].id, latlng);
CamadasService.ativarMenuCategoria(pois[0].CategoriumId);
MapaService.voarPara([
pois[0].longitude,
pois[0].latitude
]);
MapaService.piscarAzul(latlng);
}
}
});
} else {
$mdDialog.show($mdDialog.alert()
.title($scope.res('COMUM_AVISO'))
.content($scope.res('INFORMAR_RAMAL'))
.ok($scope.res('COMUM_OK')));
}
//document.getElementById("ligar").innerHTML = '<md-button class="md-primary md-raised" ng-click="desligar()" aria-label="Ligar" ><span class="ng-scope">Encerrar</span></md-button>';
}
/**
* @method desligar
*/
function desligar() {
if (VoipService.sipStack == null) {
_verfiyConfig();
return;
}
VoipService.b_mute = false;
$("#mute").show();
$("#sound").hide();
$("#making_call").show();
$("#discador").show();
$("#receiving_call").hide();
$("#in_call").hide();
$("#making_call_field").show();
$("#receiving_call_field").hide();
VoipService.displayName = '';
//document.getElementById("ligar").innerHTML = '<md-button class="md-primary md-raised" ng-click="ligar()" aria-label="Ligar" ><span class="ng-scope">Ligar</span></md-button>';
//document.getElementById("desligar").innerHTML = '<md-button class="md-primary md-raised" ng-click="desligar()" aria-label="Ligar" ></md-button>';
VoipService.sipSessionCall.o_session.hangup({
events_listener: { events: '*', listener: eventsListener }
});
stopRingBackTone();
}
/**
* @method atender
*/
function atender() {
if (VoipService.sipStack == null) {
_verfiyConfig();
return;
}
stopRingTone();
stopRingBackTone();
acceptCall();
$("#discador").hide();
$("#making_call").hide();
$("#receiving_call").hide();
$("#in_call").show();
$("#making_call_field").hide();
$("#receiving_call_field").show();
$("#mensagem").text("Ligação em andamento com o ramal " + VoipService.displayName);
if (VoipService.s_user_name != null && VoipService.s_user_name != "") {
Base.obter('pois/ramal/' + VoipService.s_user_name).then(function (pois) {
if (pois != null && pois.length > 0) {
var latlng = {
lat: pois[0].latitude,
lng: pois[0].longitude
};
Base.obter('date_server/time_millis').then(function (time_millis) {
function openWindow(url) {
var token = JSON.parse(window.sessionStorage.getItem('s4cToken')).access_token;
url = url.replace("[token]", token);
url += "&atendimento_voip=true&chave_incidente=" + time_millis;
var win = window.open(url, "Abrir incidente", "toolbar=no,location=no,directories=no,status=no,menubar=no,location=no,scrollbars=yes,resizable=yes,maximize=yes,width=" + screen.width + ",height=" + screen.height + ",top=0,left=0");
}
MapaService.voarPara([
pois[0].longitude,
pois[0].latitude
]);
MapaService.piscarAzul(latlng);
if (pois[0].extras && pois[0].extras.informacoes) {
for (var index in pois[0].extras.informacoes) {
if (pois[0].extras.informacoes[index].label == 'Comando_URL') {
var Comando_URL = pois[0].extras.informacoes[index].valor;
openWindow(Comando_URL);
}
}
}
});
}
});
}
}
/**
* @method rejeitar
*/
function rejeitar() {
if (VoipService.sipStack == null) {
_verfiyConfig();
return;
}
stopRingTone();
rejectCall();
$("#discador").show();
$("#making_call").show();
$("#receiving_call").hide();
$("#in_call").hide();
$("#making_call_field").show();
$("#receiving_call_field").hide();
$("#mensagem").text("");
}
/**
* @method deslogar
*/
function deslogar() {
if (VoipService.sipStack != null) {
VoipService.isConnected = false;
try{
VoipService.sipStack.stop();
}
catch(err){
console.log("Não foi possível deslogar do voip:");
}
}
}
/**
* @method mute
*
*/
function mute() {
VoipService.b_mute = !VoipService.b_mute;
if (VoipService.b_mute) {
$("#mute").hide();
$("#sound").show();
} else {
$("#mute").show();
$("#sound").hide();
}
VoipService.sipSessionCall.o_session.set_mute('audio', VoipService.b_mute);
}
angular.extend($scope, {
data: {},
ligar: ligar,
desligar: desligar,
atender: atender,
rejeitar: rejeitar,
mute: mute,
verificaMenuCarregado: verificaMenuCarregado,
$apivoip: {
ligar: ligar,
desligar: desligar,
atender: atender,
rejeitar: rejeitar,
deslogar: deslogar,
mute: mute,
createSipStack: createSipStack
}
});
MainState.registerDirective('voip', $scope.$apivoip);
$scope.$on('$destroy', function () {
MainState.unregisterDirective('voip');
});
/**
* @method verificaMenuCarregado
*/
function verificaMenuCarregado() {
if (!CamadasService.isLoaded && $state.current.name == "main") {
setTimeout(function () {
verificaMenuCarregado();
}, 1000);
} else {
setTimeout(function () {
var inicializado = SIPml.isInitialized();
if (!inicializado) {
SIPml.init(readyCallback, errorCallback);
} else if (SIPml.isInitialized && VoipService.sipStack == null) {
createSipStack();
} else if (VoipService.isConnected && $state.current.name == "main") {
$("#voip_button").css('opacity', '1');
}
}, 2000);
}
}
if (MainState.isToShow('voip')) {
verificaMenuCarregado();
}
}
function s4cVoip() {
return {
restrict: 'EA',
templateUrl: 'app/directives/voip/voip.html',
replace: true,
scope: {},
controller: voipCtrl
};
}
/**
* @ngdoc overview
* @name s4c.components.voip
*/
angular.module('s4c.components.voip', [])
.directive('s4cVoip', s4cVoip);
}());