Improved the external module - supports connecting on sockets, watching
message answers and option settings. git-svn-id: http://voip.null.ro/svn/yate@729 acf43c95-373e-0410-b603-e72c3f656dc1
This commit is contained in:
parent
984697273a
commit
589b63a931
|
@ -1,3 +1,10 @@
|
|||
Thu Mar 30 2006 Paul Chitescu <paulc-devel@null.ro>
|
||||
- Changed external module to allow to listen on sockets
|
||||
- Added the watch concept designed by Maciek Kaminski
|
||||
- Added many options that can be set per external module instance
|
||||
- Updated the PHP libraries to support the new functions
|
||||
- Changed the return values of GetEvent() to comply with typechecks in PHP5
|
||||
|
||||
Wed Mar 29 2006 Paul Chitescu <paulc-devel@null.ro>
|
||||
- Modified conference based on Andrew McDonald's idea of N-way mixing
|
||||
- Default output in rmanager is controlled by the config file
|
||||
|
|
|
@ -7,6 +7,28 @@
|
|||
; Uncomment the following line when running in the sources directory
|
||||
;scripts_dir=scripts/
|
||||
|
||||
; timeout: int: How many milliseconds to wait for a module to answer
|
||||
;timeout=10000
|
||||
|
||||
; timebomb: bool: Kill the module instance if it timed out
|
||||
;timebomb=false
|
||||
|
||||
|
||||
;[listener sample]
|
||||
; For each socket listener there should be a section starting with the
|
||||
; "listener" keyword
|
||||
|
||||
; type: keyword: Type of socket - "unix" or "tcp"
|
||||
|
||||
; path: string: Path of the UNIX socket to create
|
||||
|
||||
; addr: string: IP address to bind the TCP socket to
|
||||
;addr=127.0.0.1
|
||||
|
||||
; port: int: TCP port to bind to, must be positive
|
||||
|
||||
; role: keyword: Role of incoming connections - "global", "channel" or don't set
|
||||
|
||||
|
||||
[scripts]
|
||||
; Add one entry in this section for each global external module that is to be
|
||||
|
@ -17,3 +39,13 @@
|
|||
; and name relative to the sripts_dir in section [general]
|
||||
; The parameter is optional and if present is passed to the script as the first
|
||||
; (and single) parameter
|
||||
|
||||
|
||||
[execute]
|
||||
; Add one entry in this section for each external program that is to be
|
||||
; executed on Yate startup
|
||||
; Each line has to be on the form:
|
||||
; progname=parameter
|
||||
; The program name should hold the absolute path to the program
|
||||
; The parameter is optional and if present is passed to the program as the first
|
||||
; (and single) parameter
|
||||
|
|
|
@ -19,6 +19,14 @@ several file descriptors:<br />
|
|||
|
||||
File descriptors 3 and 4 are open only for audio capable applications.<br />
|
||||
|
||||
<h2>Socket operation</h2>
|
||||
Yate can start one or more socket listeners and wait for external programs to
|
||||
connect to them. Depending on the platform, TCP and UNIX sockets may be available.<br />
|
||||
Once connected, an external program uses this single socket to send commands and
|
||||
receive answers from the engine.<br />
|
||||
For reporting errors it is recommended to use the <b>%%>output</b> keyword.<br />
|
||||
Each listener can have a single role or the connecting program will have to
|
||||
use the <b>%%>connect</b> command first to esablish a role.<br />
|
||||
|
||||
<h2>Format of commands and notifications</h2>
|
||||
|
||||
|
@ -127,7 +135,7 @@ properly or not.<br />
|
|||
</p>
|
||||
|
||||
<p><b>Keyword: %%>uninstall</b><br />
|
||||
%%>install:<name><br />
|
||||
%%>uninstall:<name><br />
|
||||
<b>Direction: Application to engine</b><br />
|
||||
Always from the application to the engine, requests uninstalling a previously
|
||||
installed message handler<br />
|
||||
|
@ -136,7 +144,7 @@ The answer to the uninstall request is delivered asynchronously (see below).<br
|
|||
</p>
|
||||
|
||||
<p><b>Keyword: %%<uninstall</b><br />
|
||||
%%<install:<priority>:<name>:<success><br />
|
||||
%%<uninstall:<priority>:<name>:<success><br />
|
||||
<b>Direction: Engine to application</b><br />
|
||||
Confirmation from engine to the application that the handler has been uninstalled
|
||||
properly or not.<br />
|
||||
|
@ -145,6 +153,42 @@ properly or not.<br />
|
|||
<success> - boolean ("true" or "false") success of operation<br />
|
||||
</p>
|
||||
|
||||
<p><b>Keyword: %%>watch</b><br />
|
||||
%%>watch:<name><br />
|
||||
<b>Direction: Application to engine</b><br />
|
||||
Always from the application to the engine, requests the installing of a message
|
||||
watcher (post-dispatching notifier) for the application that requested it<br />
|
||||
The answer to the watch request is delivered asynchronously (see below).<br />
|
||||
<name> - name of the messages for that a watcher should be installed<br />
|
||||
</p>
|
||||
|
||||
<p><b>Keyword: %%<watch</b><br />
|
||||
%%<watch:<name>:<success><br />
|
||||
<b>Direction: Engine to application</b><br />
|
||||
Confirmation from engine to the application that the watcher has been installed
|
||||
properly or not.<br />
|
||||
<name> - name of the messages asked to watch<br />
|
||||
<success> - boolean ("true" or "false") success of operation<br />
|
||||
</p>
|
||||
|
||||
<p><b>Keyword: %%>unwatch</b><br />
|
||||
%%>unwatch:<name><br />
|
||||
<b>Direction: Application to engine</b><br />
|
||||
Always from the application to the engine, requests uninstalling a previously
|
||||
installed message watcher<br />
|
||||
The answer to the unwatch request is delivered asynchronously (see below).<br />
|
||||
<name> - name of the message watcher thst should be uninstalled<br />
|
||||
</p>
|
||||
|
||||
<p><b>Keyword: %%<unwatch</b><br />
|
||||
%%<unwatch:<name>:<success><br />
|
||||
<b>Direction: Engine to application</b><br />
|
||||
Confirmation from engine to the application that the watcher has been uninstalled
|
||||
properly or not.<br />
|
||||
<name> - name of the message watcher asked to uninstall<br />
|
||||
<success> - boolean ("true" or "false") success of operation<br />
|
||||
</p>
|
||||
|
||||
<p><b>Keyword: %%>setlocal</b><br />
|
||||
%%>setlocal:<name>:<value><br />
|
||||
<b>Direction: Application to engine</b><br />
|
||||
|
@ -152,7 +196,14 @@ Always from the application to the engine, requests the change of a local
|
|||
parameter<br />
|
||||
The answer to the change request is delivered asynchronously (see below).<br />
|
||||
<name> - name of the parameter to modify, must not be empty<br />
|
||||
<value> - new value to set in the local module instance<br />
|
||||
<value> - new value to set in the local module instance, empty to just query<br />
|
||||
<b>Currently supported parameters:</b><br />
|
||||
id (string) - Identifier of the associated channel, if any<br />
|
||||
disconnected (bool) - Enable or disable sending "chan.disconnected" messages<br />
|
||||
timeout (int) - Timeout in milliseconds for answering to messages<br />
|
||||
timebomb (bool) - Terminate this module instance if a timeout occured<br />
|
||||
reenter (bool) - If this module is allowed to handle messages generated by itself<br />
|
||||
selfwatch (bool) - If this module is allowed to watch messages generated by itself<br />
|
||||
</p>
|
||||
|
||||
<p><b>Keyword: %%<setlocal</b><br />
|
||||
|
@ -165,6 +216,15 @@ changed successfully or not.<br />
|
|||
<success> - boolean ("true" or "false") success of operation<br />
|
||||
</p>
|
||||
|
||||
<p><b>Keyword: %%>output</b><br />
|
||||
%%>output:arbitrary unescaped string<br />
|
||||
<b>Direction: Application to engine</b><br />
|
||||
The "output" keyword is used to relay arbitrary output messages to
|
||||
engine's logging output.<br />
|
||||
This is the proper way of logging messages for programs that connect to the
|
||||
socket interface as they may not have the standard error redirected.<br />
|
||||
</p>
|
||||
|
||||
<p><b>Keyword: %%>connect</b><br />
|
||||
%%>connect:<role>[:<id>][:<type>]<br />
|
||||
<b>Direction: Application to engine</b><br />
|
||||
|
|
|
@ -282,6 +282,16 @@ Stream::~Stream()
|
|||
{
|
||||
}
|
||||
|
||||
bool Stream::canRetry() const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Stream::setBlocking(bool block)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
int Stream::writeData(const char* str)
|
||||
{
|
||||
if (null(str))
|
||||
|
@ -422,6 +432,37 @@ void File::copyError()
|
|||
#endif
|
||||
}
|
||||
|
||||
bool File::canRetry() const
|
||||
{
|
||||
if (!m_error)
|
||||
return true;
|
||||
return (m_error == EAGAIN) || (m_error == EINTR) || (m_error == EWOULDBLOCK);
|
||||
}
|
||||
|
||||
bool File::setBlocking(bool block)
|
||||
{
|
||||
#ifdef _WINDOWS
|
||||
return false;
|
||||
#else
|
||||
unsigned long flags = 1;
|
||||
flags = ::fcntl(m_handle,F_GETFL);
|
||||
if (flags < 0) {
|
||||
copyError();
|
||||
return false;
|
||||
}
|
||||
if (block)
|
||||
flags &= !O_NONBLOCK;
|
||||
else
|
||||
flags |= O_NONBLOCK;
|
||||
if (::fcntl(m_handle,F_SETFL,flags) < 0) {
|
||||
copyError();
|
||||
return false;
|
||||
}
|
||||
clearError();
|
||||
return true;
|
||||
#endif
|
||||
}
|
||||
|
||||
int File::writeData(const void* buffer, int length)
|
||||
{
|
||||
if (!buffer)
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -129,10 +129,10 @@ function gotNotify()
|
|||
while ($state != "") {
|
||||
$ev=Yate::GetEvent();
|
||||
/* If Yate disconnected us then exit cleanly */
|
||||
if ($ev == "EOF")
|
||||
if ($ev === false)
|
||||
break;
|
||||
/* No need to handle empty events in this application */
|
||||
if ($ev == "")
|
||||
if ($ev === true)
|
||||
continue;
|
||||
/* If we reached here we should have a valid object */
|
||||
switch ($ev->type) {
|
||||
|
@ -158,7 +158,7 @@ while ($state != "") {
|
|||
setState("novmail");
|
||||
|
||||
// we already ACKed this message
|
||||
$ev = "";
|
||||
$ev = false;
|
||||
break;
|
||||
|
||||
case "chan.notify":
|
||||
|
@ -170,7 +170,7 @@ while ($state != "") {
|
|||
}
|
||||
/* This is extremely important.
|
||||
We MUST let messages return, handled or not */
|
||||
if ($ev != "")
|
||||
if ($ev)
|
||||
$ev->Acknowledge();
|
||||
break;
|
||||
case "answer":
|
||||
|
|
|
@ -56,8 +56,11 @@ class Yate
|
|||
*/
|
||||
static function Output($str)
|
||||
{
|
||||
global $yate_stderr;
|
||||
fputs($yate_stderr, $str . "\n");
|
||||
global $yate_stderr, $yate_socket;
|
||||
if ($yate_socket)
|
||||
_yate_print("%%>output:$str\n");
|
||||
else
|
||||
fputs($yate_stderr, "$str\n");
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -73,7 +76,18 @@ class Yate
|
|||
else if ($str === false)
|
||||
$yate_debug = false;
|
||||
else if ($yate_debug)
|
||||
fputs($yate_stderr, $str . "\n");
|
||||
Yate::Output($str);
|
||||
}
|
||||
|
||||
/**
|
||||
* Static function to get the unique argument passed by Yate at start time
|
||||
* @return First (and only) command line argument passed by Yate
|
||||
*/
|
||||
static function Arg()
|
||||
{
|
||||
if (isset($_SERVER['argv'][1]))
|
||||
return $_SERVER['argv'][1];
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -154,7 +168,7 @@ class Yate
|
|||
$name=Yate::Escape($name);
|
||||
if ($filtname)
|
||||
$filtname=":$filtname:$filtvalue";
|
||||
print "%%>install:$priority:$name$filtname\n";
|
||||
_yate_print("%%>install:$priority:$name$filtname\n");
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -164,7 +178,27 @@ class Yate
|
|||
static function Uninstall($name)
|
||||
{
|
||||
$name=Yate::Escape($name);
|
||||
print "%%>uninstall:$name\n";
|
||||
_yate_print("%%>uninstall:$name\n");
|
||||
}
|
||||
|
||||
/**
|
||||
* Install a Yate message watcher
|
||||
* @param $name Name of the messages to watch
|
||||
*/
|
||||
static function Watch($name)
|
||||
{
|
||||
$name=Yate::Escape($name);
|
||||
_yate_print("%%>watch:$name\n");
|
||||
}
|
||||
|
||||
/**
|
||||
* Uninstall a Yate message watcher
|
||||
* @param $name Name of the messages to stop watching
|
||||
*/
|
||||
static function Unwatch($name)
|
||||
{
|
||||
$name=Yate::Escape($name);
|
||||
_yate_print("%%>unwatch:$name\n");
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -176,7 +210,7 @@ class Yate
|
|||
{
|
||||
$name=Yate::Escape($name);
|
||||
$value=Yate::Escape($value);
|
||||
print "%%>setlocal:$name:$value\n";
|
||||
_yate_print("%%>setlocal:$name:$value\n");
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -211,6 +245,18 @@ class Yate
|
|||
return $defvalue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a named parameter
|
||||
* @param $key Name of the parameter to set
|
||||
* @param $value Value to set in the parameter
|
||||
*/
|
||||
function SetParam($key, $value)
|
||||
{
|
||||
if (($value === true) || ($value === false))
|
||||
$value = Yate::Bool2str($value);
|
||||
$this->params[$key] = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fill the parameter array from a text representation
|
||||
* @param $parts A numerically indexed array with the key=value parameters
|
||||
|
@ -246,7 +292,7 @@ class Yate
|
|||
$p="";
|
||||
$pa = array(&$p);
|
||||
array_walk($this->params, "_yate_message_walk", $pa);
|
||||
print "%%>message:$i:$t:$n:$r$p\n";
|
||||
_yate_print("%%>message:$i:$t:$n:$r$p\n");
|
||||
$this->type="dispatched";
|
||||
}
|
||||
|
||||
|
@ -267,28 +313,44 @@ class Yate
|
|||
$p="";
|
||||
$pa = array(&$p);
|
||||
array_walk($this->params, "_yate_message_walk", $pa);
|
||||
print "%%<message:$i:$k:$n:$r$p\n";
|
||||
_yate_print("%%<message:$i:$k:$n:$r$p\n");
|
||||
$this->type="acknowledged";
|
||||
}
|
||||
|
||||
/**
|
||||
* This static function processes just one input line.
|
||||
* It must be called in a loop to keep messages running. Or else.
|
||||
* @return "EOF" if we should exit, "" if we should keep running,
|
||||
* or an Yate object instance
|
||||
* @return false if we should exit, true if we should keep running,
|
||||
* or an Yate object instance. Remember to use === and !== operators
|
||||
* when comparing against true and false.
|
||||
*/
|
||||
static function GetEvent()
|
||||
{
|
||||
global $yate_stdin;
|
||||
if (feof($yate_stdin))
|
||||
return "EOF";
|
||||
$line=fgets($yate_stdin,4096);
|
||||
if ($line == false)
|
||||
return "";
|
||||
global $yate_stdin, $yate_socket;
|
||||
if ($yate_socket) {
|
||||
$line = @socket_read($yate_socket,8192);
|
||||
// check for error
|
||||
if ($line == false)
|
||||
return false;
|
||||
// check for EOF
|
||||
if ($line === "")
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
if ($yate_stdin == false)
|
||||
return false;
|
||||
// check for EOF
|
||||
if (feof($yate_stdin))
|
||||
return false;
|
||||
$line=fgets($yate_stdin,8192);
|
||||
// check for async read no data
|
||||
if ($line == false)
|
||||
return true;
|
||||
}
|
||||
$line=str_replace("\n", "", $line);
|
||||
if ($line == "")
|
||||
return "";
|
||||
$ev="";
|
||||
return true;
|
||||
$ev=true;
|
||||
$part=explode(":", $line);
|
||||
switch ($part[0]) {
|
||||
case "%%>message":
|
||||
|
@ -317,6 +379,24 @@ class Yate
|
|||
$ev->type="uninstalled";
|
||||
$ev->handled=Yate::Str2bool($part[3]);
|
||||
break;
|
||||
case "%%<watch":
|
||||
/* watch answer str_name:bool_success */
|
||||
$ev=new Yate(Yate::Unescape($part[1]));
|
||||
$ev->type="watched";
|
||||
$ev->handled=Yate::Str2bool($part[2]);
|
||||
break;
|
||||
case "%%<unwatch":
|
||||
/* unwatch answer str_name:bool_success */
|
||||
$ev=new Yate(Yate::Unescape($part[1]));
|
||||
$ev->type="unwatched";
|
||||
$ev->handled=Yate::Str2bool($part[2]);
|
||||
break;
|
||||
case "%%<connect":
|
||||
/* connect answer str_role:bool_success */
|
||||
$ev=new Yate(Yate::Unescape($part[1]));
|
||||
$ev->type="connected";
|
||||
$ev->handled=Yate::Str2bool($part[2]);
|
||||
break;
|
||||
case "%%<setlocal":
|
||||
/* local parameter answer str_name:str_value:bool_success */
|
||||
$ev=new Yate(Yate::Unescape($part[1]),Yate::Unescape($part[2]));
|
||||
|
@ -336,19 +416,50 @@ class Yate
|
|||
* This static function initializes globals in the PHP Yate External Module.
|
||||
* It should be called before any other method.
|
||||
* @param $async (optional) True if asynchronous, polled mode is desired
|
||||
* @param $addr Hostname to connect to or UNIX socket path
|
||||
* @param $port TCP port to connect to, zero to use UNIX sockets
|
||||
* @param $role Role of this connection - "global" or "channel"
|
||||
* @return True if initialization succeeded, false if failed
|
||||
*/
|
||||
static function Init($async = false)
|
||||
static function Init($async = false, $addr = "", $port = 0, $role = "")
|
||||
{
|
||||
global $yate_stdin, $yate_stdout, $yate_stderr, $yate_debug;
|
||||
global $yate_stdin, $yate_stdout, $yate_stderr, $yate_socket, $yate_debug;
|
||||
$yate_debug = false;
|
||||
$yate_stdin = fopen("php://stdin","r");
|
||||
$yate_stdout = fopen("php://stdout","w");
|
||||
$yate_stderr = fopen("php://stderr","w");
|
||||
$yate_stdin = false;
|
||||
$yate_stdout = false;
|
||||
$yate_stderr = false;
|
||||
if ($addr) {
|
||||
$ok = false;
|
||||
if ($port) {
|
||||
$yate_socket = @socket_create(AF_INET,SOCK_STREAM,SOL_TCP);
|
||||
$ok = @socket_connect($yate_socket,$addr,$port);
|
||||
}
|
||||
else {
|
||||
$yate_socket = @socket_create(AF_UNIX,SOCK_STREAM,0);
|
||||
$ok = @socket_connect($yate_socket,$addr,$port);
|
||||
}
|
||||
if (($yate_socket === false) || !$ok) {
|
||||
$yate_socket = false;
|
||||
$yate_stderr = fopen("php://stderr","w");
|
||||
Yate::Output("Socket error, initialization failed");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else {
|
||||
$yate_socket = false;
|
||||
$yate_stdin = fopen("php://stdin","r");
|
||||
$yate_stdout = fopen("php://stdout","w");
|
||||
$yate_stderr = fopen("php://stderr","w");
|
||||
$role = "";
|
||||
}
|
||||
flush();
|
||||
set_error_handler("_yate_error_handler");
|
||||
ob_implicit_flush(1);
|
||||
if ($async && function_exists("stream_set_blocking"))
|
||||
if ($async && function_exists("stream_set_blocking") && $yate_stdin)
|
||||
stream_set_blocking($yate_stdin,false);
|
||||
if ($role)
|
||||
_yate_print("%%>connect:$role\n");
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -359,22 +470,32 @@ function _yate_error_handler($errno, $errstr, $errfile, $errline)
|
|||
$str = " [$errno] $errstr in $errfile line $errline\n";
|
||||
switch ($errno) {
|
||||
case E_USER_ERROR:
|
||||
Yate::Output("PHP fatal:" . $str);
|
||||
Yate::Output("PHP fatal: $str");
|
||||
exit(1);
|
||||
break;
|
||||
case E_WARNING:
|
||||
case E_USER_WARNING:
|
||||
Yate::Output("PHP error:" . $str);
|
||||
Yate::Output("PHP error: $str");
|
||||
break;
|
||||
case E_NOTICE:
|
||||
case E_USER_NOTICE:
|
||||
Yate::Output("PHP warning:" . $str);
|
||||
Yate::Output("PHP warning: $str");
|
||||
break;
|
||||
default:
|
||||
Yate::Output("PHP unknown error:" . $str);
|
||||
Yate::Output("PHP unknown error: $str");
|
||||
}
|
||||
}
|
||||
|
||||
/* Internal function */
|
||||
function _yate_print($str)
|
||||
{
|
||||
global $yate_stdout, $yate_socket;
|
||||
if ($yate_socket)
|
||||
@socket_write($yate_socket, $str);
|
||||
else if ($yate_stdout)
|
||||
fputs($yate_stdout, $str);
|
||||
}
|
||||
|
||||
/* Internal function */
|
||||
function _yate_message_walk($item, $key, &$result)
|
||||
{
|
||||
|
|
|
@ -69,9 +69,9 @@ class YateChan
|
|||
$loop = true;
|
||||
while ($loop) {
|
||||
$ev=Yate::GetEvent();
|
||||
if ($ev == "")
|
||||
if ($ev === true)
|
||||
continue;
|
||||
if ($ev == "EOF") {
|
||||
if ($ev === false) {
|
||||
$chan_instance->exiting = true;
|
||||
break;
|
||||
}
|
||||
|
@ -208,11 +208,13 @@ class YateChan
|
|||
* It will call Yate::Init internally.
|
||||
* @param $prefix (optional) Prefix used for the unique channel identifier
|
||||
* @param $async (optional) True if asynchronous, polled mode is desired
|
||||
* @param $addr Hostname to connect to or UNIX socket path
|
||||
* @param $port TCP port to connect to, zero to use UNIX sockets
|
||||
*/
|
||||
static function Init($prefix = "extchan", $async = false)
|
||||
static function Init($prefix = "extchan", $async = false, $addr = "", $port = 0)
|
||||
{
|
||||
global $chan_instance;
|
||||
Yate::Init($async);
|
||||
Yate::Init($async,$addr,$port,"channel");
|
||||
$chan_instance = new YateChan($prefix);
|
||||
YateChan::RunEvents();
|
||||
if ($chan_instance->exiting)
|
||||
|
|
|
@ -163,9 +163,9 @@ function endRoute($callto,$ok,$err)
|
|||
while ($state != "") {
|
||||
$ev=Yate::GetEvent();
|
||||
/* If Yate disconnected us then exit cleanly */
|
||||
if ($ev == "EOF")
|
||||
if ($ev === false)
|
||||
break;
|
||||
if ($ev == "")
|
||||
if ($ev === true)
|
||||
continue;
|
||||
/* If we reached here we should have a valid object */
|
||||
switch ($ev->type) {
|
||||
|
@ -179,7 +179,7 @@ while ($state != "") {
|
|||
// we must ACK this message before dispatching a call.answered
|
||||
$ev->Acknowledge();
|
||||
// we already ACKed this message
|
||||
$ev = "";
|
||||
$ev = false;
|
||||
|
||||
$m = new Yate("call.answered");
|
||||
$m->params["id"] = $ourcallid;
|
||||
|
@ -207,7 +207,7 @@ while ($state != "") {
|
|||
}
|
||||
/* This is extremely important.
|
||||
We MUST let messages return, handled or not */
|
||||
if ($ev != "")
|
||||
if ($ev)
|
||||
$ev->Acknowledge();
|
||||
break;
|
||||
case "answer":
|
||||
|
|
|
@ -130,11 +130,11 @@ function gotDTMF($text)
|
|||
while ($state != "") {
|
||||
$ev=Yate::GetEvent();
|
||||
/* If Yate disconnected us then exit cleanly */
|
||||
if ($ev == "EOF")
|
||||
if ($ev === false)
|
||||
break;
|
||||
/* Empty events are normal in non-blocking operation.
|
||||
This is an opportunity to do idle tasks and check timers */
|
||||
if ($ev == "")
|
||||
if ($ev === true)
|
||||
continue;
|
||||
/* If we reached here we should have a valid object */
|
||||
switch ($ev->type) {
|
||||
|
@ -147,7 +147,7 @@ while ($state != "") {
|
|||
// we must ACK this message before dispatching a call.answered
|
||||
$ev->Acknowledge();
|
||||
// we already ACKed this message
|
||||
$ev = "";
|
||||
$ev = false;
|
||||
|
||||
$m = new Yate("call.answered");
|
||||
$m->params["id"] = $ourcallid;
|
||||
|
@ -175,7 +175,7 @@ while ($state != "") {
|
|||
}
|
||||
/* This is extremely important.
|
||||
We MUST let messages return, handled or not */
|
||||
if ($ev != "")
|
||||
if ($ev)
|
||||
$ev->Acknowledge();
|
||||
break;
|
||||
case "answer":
|
||||
|
|
|
@ -20,11 +20,11 @@ Yate::Install("user.auth",10);
|
|||
for (;;) {
|
||||
$ev=Yate::GetEvent();
|
||||
/* If Yate disconnected us then exit cleanly */
|
||||
if ($ev == "EOF")
|
||||
if ($ev === false)
|
||||
break;
|
||||
/* Empty events are normal in non-blocking operation.
|
||||
This is an opportunity to do idle tasks and check timers */
|
||||
if ($ev == "") {
|
||||
if ($ev === true) {
|
||||
// Yate::Output("PHP event: empty");
|
||||
continue;
|
||||
}
|
||||
|
|
|
@ -26,11 +26,11 @@ $m->Dispatch();
|
|||
for (;;) {
|
||||
$ev=Yate::GetEvent();
|
||||
/* If Yate disconnected us then exit cleanly */
|
||||
if ($ev == "EOF")
|
||||
if ($ev === false)
|
||||
break;
|
||||
/* Empty events are normal in non-blocking operation.
|
||||
This is an opportunity to do idle tasks and check timers */
|
||||
if ($ev == "") {
|
||||
if ($ev === true) {
|
||||
// Yate::Output("PHP event: empty");
|
||||
continue;
|
||||
}
|
||||
|
|
|
@ -24,11 +24,11 @@ $m->Dispatch();
|
|||
for (;;) {
|
||||
$ev=Yate::GetEvent();
|
||||
/* If Yate disconnected us then exit cleanly */
|
||||
if ($ev == "EOF")
|
||||
if ($ev === false)
|
||||
break;
|
||||
/* Empty events are normal in non-blocking operation.
|
||||
This is an opportunity to do idle tasks and check timers */
|
||||
if ($ev == "") {
|
||||
if ($ev === true) {
|
||||
Yate::Output("PHP event: empty");
|
||||
continue;
|
||||
}
|
||||
|
|
|
@ -324,10 +324,10 @@ function gotDTMF($text)
|
|||
while ($state != "") {
|
||||
$ev=Yate::GetEvent();
|
||||
/* If Yate disconnected us then exit cleanly */
|
||||
if ($ev == "EOF")
|
||||
if ($ev === false)
|
||||
break;
|
||||
/* No need to handle empty events in this application */
|
||||
if ($ev == "")
|
||||
if ($ev === true)
|
||||
continue;
|
||||
/* If we reached here we should have a valid object */
|
||||
switch ($ev->type) {
|
||||
|
@ -341,7 +341,7 @@ while ($state != "") {
|
|||
/* We must ACK this message before dispatching a call.answered */
|
||||
$ev->Acknowledge();
|
||||
/* Prevent a warning if trying to ACK this message again */
|
||||
$ev = "";
|
||||
$ev = false;
|
||||
|
||||
/* Signal we are answering the call */
|
||||
$m = new Yate("call.answered");
|
||||
|
@ -374,7 +374,7 @@ while ($state != "") {
|
|||
}
|
||||
/* This is extremely important.
|
||||
We MUST let messages return, handled or not */
|
||||
if ($ev != "")
|
||||
if ($ev)
|
||||
$ev->Acknowledge();
|
||||
break;
|
||||
case "answer":
|
||||
|
|
30
yateclass.h
30
yateclass.h
|
@ -3149,12 +3149,25 @@ public:
|
|||
*/
|
||||
virtual bool terminate() = 0;
|
||||
|
||||
/**
|
||||
* Check if the last error code indicates a retryable condition
|
||||
* @return True if error was temporary and operation should be retried
|
||||
*/
|
||||
virtual bool canRetry() const;
|
||||
|
||||
/**
|
||||
* Check if this stream is valid
|
||||
* @return True if the stream is valid, false if it's invalid or closed
|
||||
*/
|
||||
virtual bool valid() const = 0;
|
||||
|
||||
/**
|
||||
* Set the blocking or non-blocking operation mode of the stream
|
||||
* @param block True if I/O operations should block, false for non-blocking
|
||||
* @return True if operation was successfull, false if an error occured
|
||||
*/
|
||||
virtual bool setBlocking(bool block = true);
|
||||
|
||||
/**
|
||||
* Write data to a connected stream
|
||||
* @param buffer Buffer for data transfer
|
||||
|
@ -3287,6 +3300,12 @@ public:
|
|||
inline HANDLE handle() const
|
||||
{ return m_handle; }
|
||||
|
||||
/**
|
||||
* Check if the last error code indicates a retryable condition
|
||||
* @return True if error was temporary and operation should be retried
|
||||
*/
|
||||
virtual bool canRetry() const;
|
||||
|
||||
/**
|
||||
* Check if this file is valid
|
||||
* @return True if the file is valid, false if it's invalid or closed
|
||||
|
@ -3299,6 +3318,13 @@ public:
|
|||
*/
|
||||
static HANDLE invalidHandle();
|
||||
|
||||
/**
|
||||
* Set the blocking or non-blocking operation mode of the file
|
||||
* @param block True if I/O operations should block, false for non-blocking
|
||||
* @return True if operation was successfull, false if an error occured
|
||||
*/
|
||||
virtual bool setBlocking(bool block = true);
|
||||
|
||||
/**
|
||||
* Write data to an open file
|
||||
* @param buffer Buffer for data transfer
|
||||
|
@ -3419,7 +3445,7 @@ public:
|
|||
* Check if the last error code indicates a retryable condition
|
||||
* @return True if error was temporary and operation should be retried
|
||||
*/
|
||||
bool canRetry() const;
|
||||
virtual bool canRetry() const;
|
||||
|
||||
/**
|
||||
* Check if this socket is valid
|
||||
|
@ -3469,7 +3495,7 @@ public:
|
|||
* @param block True if I/O operations should block, false for non-blocking
|
||||
* @return True if operation was successfull, false if an error occured
|
||||
*/
|
||||
bool setBlocking(bool block = true);
|
||||
virtual bool setBlocking(bool block = true);
|
||||
|
||||
/**
|
||||
* Associates the socket with a local address
|
||||
|
|
Loading…
Reference in New Issue