mirror of https://github.com/movim/movim
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
292 lines
8.2 KiB
292 lines
8.2 KiB
<?php
|
|
|
|
use Moxl\Xec\Action\Jingle\SessionPropose;
|
|
use Moxl\Xec\Action\Jingle\SessionAccept;
|
|
use Moxl\Xec\Action\Jingle\SessionInitiate;
|
|
use Moxl\Xec\Action\Jingle\SessionTerminate;
|
|
|
|
use Movim\Widget\Base;
|
|
use Movim\Session;
|
|
|
|
class Visio extends Base
|
|
{
|
|
public function load()
|
|
{
|
|
$this->addcss('visio.css');
|
|
$this->addjs('visio.js');
|
|
$this->addjs('visio_utils.js');
|
|
|
|
$this->registerEvent('jinglepropose', 'onPropose');
|
|
$this->registerEvent('jingleproceed', 'onProceed');
|
|
$this->registerEvent('jingleaccept', 'onAccept');
|
|
$this->registerEvent('jingleretract', 'onTerminateRetract');
|
|
$this->registerEvent('jinglereject', 'onTerminateReject');
|
|
$this->registerEvent('jingle_sessioninitiate', 'onInitiateSDP');
|
|
$this->registerEvent('jingle_sessioninitiate_erroritemnotfound', 'onTerminateNotFound');
|
|
$this->registerEvent('jingle_sessionaccept', 'onAcceptSDP');
|
|
$this->registerEvent('jingle_transportinfo', 'onCandidate');
|
|
$this->registerEvent('jingle_sessionterminate', 'onTerminate');
|
|
$this->registerEvent('externalservices_get_handle', 'onExternalServices');
|
|
$this->registerEvent('externalservices_get_error', 'onExternalServicesError');
|
|
}
|
|
|
|
public function onExternalServices($packet)
|
|
{
|
|
$externalServices = [];
|
|
if ($packet->content) {
|
|
$turn = $stun = false;
|
|
foreach ($packet->content as $service) {
|
|
// One STUN/TURN server max
|
|
if ($service['type'] == 'stun' && $stun) continue;
|
|
if ($service['type'] == 'stun') $stun = true;
|
|
if ($service['type'] == 'turn' && $turn) continue;
|
|
if ($service['type'] == 'turn') $turn = true;
|
|
|
|
$url = $service['type'].':'.$service['host'];
|
|
$url .= !empty($service['port']) ? ':'.$service['port'] : '';
|
|
$item = ['urls' => $url];
|
|
|
|
if (isset($service['username']) && isset($service['password'])) {
|
|
$item['username'] = $service['username'];
|
|
$item['credential'] = $service['password'];
|
|
}
|
|
|
|
array_push($externalServices, $item);
|
|
}
|
|
}
|
|
|
|
if (!empty($externalServices)) {
|
|
$this->rpc('Visio.setServices', $externalServices);
|
|
} else {
|
|
$this->setDefaultServices();
|
|
}
|
|
|
|
$this->rpc('Visio.init');
|
|
}
|
|
|
|
public function onExternalServicesError($packet)
|
|
{
|
|
$this->setDefaultServices();
|
|
$this->rpc('Visio.init');
|
|
}
|
|
|
|
public function onPropose($packet)
|
|
{
|
|
$data = $packet->content;
|
|
|
|
$contact = \App\Contact::firstOrNew(['id' => cleanJid($data['from'])]);
|
|
|
|
$view = $this->tpl();
|
|
$view->assign('contact', $contact);
|
|
$view->assign('from', $data['from']);
|
|
$view->assign('id', $data['id']);
|
|
$view->assign('withvideo', $data['withVideo']);
|
|
|
|
Dialog::fill($view->draw('_visio_dialog'), false, true);
|
|
|
|
$this->rpc('Notification.incomingCall');
|
|
|
|
$withVideoParameter = $data['withVideo']
|
|
? 'true'
|
|
: 'false';
|
|
|
|
Notification::append(
|
|
'call',
|
|
$contact->truename,
|
|
$this->__('visio.calling'),
|
|
$contact->getPhoto(),
|
|
5,
|
|
null,
|
|
null,
|
|
'VisioLink.openVisio(\''.$data['from'].'\', \''.$data['id'].'\', '.$withVideoParameter.'); Dialog_ajaxClear()'
|
|
);
|
|
}
|
|
|
|
public function onInitiateSDP($data)
|
|
{
|
|
list($stanza, $from) = $data;
|
|
|
|
$jts = new JingletoSDP($stanza);
|
|
|
|
$this->rpc('Visio.onInitiateSDP', $jts->generate());
|
|
}
|
|
|
|
public function onProceed($packet)
|
|
{
|
|
$data = $packet->content;
|
|
$this->rpc('Visio.onProceed', $data['from'], $data['id']);
|
|
}
|
|
|
|
public function onAccept($packet)
|
|
{
|
|
$this->rpc('Notification.incomingAnswer');
|
|
(new Dialog)->ajaxClear();
|
|
}
|
|
|
|
public function onAcceptSDP($stanza)
|
|
{
|
|
$jts = new JingletoSDP($stanza);
|
|
$this->rpc('Visio.onAcceptSDP', $jts->generate());
|
|
}
|
|
|
|
public function onCandidate($stanza)
|
|
{
|
|
$jts = new JingletoSDP($stanza);
|
|
$sdp = $jts->generate();
|
|
|
|
$this->rpc('Visio.onCandidate', $sdp, (string)$jts->name, $jts->name);
|
|
}
|
|
|
|
public function onTerminateRetract()
|
|
{
|
|
$this->onTerminate('retract');
|
|
}
|
|
|
|
public function onTerminateReject()
|
|
{
|
|
$this->onTerminate('reject');
|
|
}
|
|
|
|
public function onTerminateNotFound()
|
|
{
|
|
$this->onTerminate('notfound');
|
|
}
|
|
|
|
public function onTerminate($reason)
|
|
{
|
|
// Stop calling sound and clear the Dialog if there
|
|
$this->rpc('Notification.incomingAnswer');
|
|
(new Dialog)->ajaxClear();
|
|
|
|
$this->rpc('Visio.onTerminate', $reason);
|
|
}
|
|
|
|
public function ajaxPropose($to, $id, $withVideo = false)
|
|
{
|
|
$p = new SessionPropose;
|
|
$p->setTo($to)
|
|
->setId($id)
|
|
->setWithVideo($withVideo)
|
|
->request();
|
|
}
|
|
|
|
public function ajaxAccept($to, $id)
|
|
{
|
|
Session::start()->set('jingleSid', $id);
|
|
|
|
$p = new SessionAccept;
|
|
$p->setTo($to)
|
|
->setId($id)
|
|
->request();
|
|
}
|
|
|
|
public function ajaxSessionInitiate($sdp, $to, $id)
|
|
{
|
|
$stj = new SDPtoJingle(
|
|
$sdp->sdp,
|
|
$this->user->id,
|
|
$to,
|
|
'session-initiate'
|
|
);
|
|
$stj->setSessionId($id);
|
|
|
|
$si = new SessionInitiate;
|
|
$si->setTo($to)
|
|
->setOffer($stj->generate())
|
|
->request();
|
|
}
|
|
|
|
public function ajaxResolveServices()
|
|
{
|
|
$info = \App\Info::where('server', $this->user->session->host)
|
|
->where('node', '')
|
|
->first();
|
|
if ($info && $info->hasExternalServices()) {
|
|
$c = new \Moxl\Xec\Action\ExternalServices\Get;
|
|
$c->setTo($this->user->session->host)
|
|
->request();
|
|
} else {
|
|
$this->setDefaultServices();
|
|
$this->rpc('Visio.init');
|
|
}
|
|
}
|
|
|
|
public function setDefaultServices()
|
|
{
|
|
$servers = [
|
|
'stun:stun01.sipphone.com',
|
|
'stun:stun.ekiga.net',
|
|
'stun:stun.fwdnet.net',
|
|
'stun:stun.ideasip.com',
|
|
'stun:stun.iptel.org',
|
|
'stun:stun.rixtelecom.se',
|
|
'stun:stun.schlund.de',
|
|
'stun:stun.l.google.com:19305',
|
|
'stun:stun1.l.google.com:19305',
|
|
'stun:stun2.l.google.com:19305',
|
|
'stun:stun3.l.google.com:19305',
|
|
'stun:stun4.l.google.com:19305',
|
|
'stun:stunserver.org',
|
|
'stun:stun.softjoys.com',
|
|
'stun:stun.voiparound.com',
|
|
'stun:stun.voipbuster.com',
|
|
'stun:stun.voipstunt.com',
|
|
'stun:stun.voxgratia.org',
|
|
'stun:stun.xten.com'
|
|
];
|
|
|
|
shuffle($servers);
|
|
$this->rpc('Visio.setServices', [['urls' => array_slice($servers, 0, 2)]]);
|
|
}
|
|
|
|
public function ajaxSessionAccept($sdp, $to, $id)
|
|
{
|
|
$stj = new SDPtoJingle(
|
|
$sdp->sdp,
|
|
$this->user->id,
|
|
$to,
|
|
'session-accept'
|
|
);
|
|
$stj->setSessionId($id);
|
|
|
|
$si = new SessionInitiate;
|
|
$si->setTo($to)
|
|
->setOffer($stj->generate())
|
|
->request();
|
|
}
|
|
|
|
public function ajaxCandidate($sdp, $to, $id)
|
|
{
|
|
$stj = new SDPtoJingle(
|
|
'a='.$sdp->candidate,
|
|
$this->user->id,
|
|
$to,
|
|
'transport-info',
|
|
$sdp->sdpMid,
|
|
$sdp->usernameFragment
|
|
);
|
|
$stj->setSessionId($id);
|
|
|
|
$si = new SessionInitiate;
|
|
$si->setTo($to)
|
|
->setOffer($stj->generate())
|
|
->request();
|
|
}
|
|
|
|
public function ajaxTerminate($to, $reason = 'success', $sid)
|
|
{
|
|
Session::start()->remove('jingleSid');
|
|
|
|
$st = new SessionTerminate;
|
|
$st->setTo($to)
|
|
->setJingleSid($sid)
|
|
->setReason($reason)
|
|
->request();
|
|
}
|
|
|
|
public function display()
|
|
{
|
|
$this->view->assign('withvideo', $this->getView() == 'visio');
|
|
$this->view->assign('contact', \App\Contact::firstOrNew(['id' => $this->get('f')]));
|
|
}
|
|
}
|