[Freeswitch-svn] [commit] r7147 - in freeswitch/trunk/scripts/contrib/intralanman/PHP: . fs_sock

Freeswitch SVN intralanman at freeswitch.org
Tue Jan 8 16:55:23 EST 2008


Author: intralanman
Date: Tue Jan  8 16:55:23 2008
New Revision: 7147

Added:
   freeswitch/trunk/scripts/contrib/intralanman/PHP/
   freeswitch/trunk/scripts/contrib/intralanman/PHP/fs_sock/
   freeswitch/trunk/scripts/contrib/intralanman/PHP/fs_sock/fs_sock.php
   freeswitch/trunk/scripts/contrib/intralanman/PHP/fs_sock/socktest.php

Log:
adding PHP class for event socket

Added: freeswitch/trunk/scripts/contrib/intralanman/PHP/fs_sock/fs_sock.php
==============================================================================
--- (empty file)
+++ freeswitch/trunk/scripts/contrib/intralanman/PHP/fs_sock/fs_sock.php	Tue Jan  8 16:55:23 2008
@@ -0,0 +1,420 @@
+<?php
+/**
+ * Class for FreeSWITCH event socket
+ *
+ */
+
+/**
+ * Class for FreeSWITCH event socket
+ *
+ */
+class fs_sock {
+    /**
+     * file handler for FreeSWITCH socket connection
+     *
+     * @var file pointer
+     */
+    public $sock;
+
+    /**
+     * Sets Whether auth was successful or not
+     * Used to not send further commands until auth is successful
+     *
+     * @var boolean
+     */
+    public $auth;
+
+    /**
+     * Variable to hold current command
+     *
+     * @var string
+     */
+    private $command = 'initial_read';
+
+    private $input_buffer;
+    private $output_buffer;
+
+    /**
+     * Class instantiation
+     * This method will connect to the socket and authenticate
+     *
+     * @param array $vars
+     * @return fs_sock
+     */
+    function fs_sock($vars=null) {
+        if (!defined('BUFFER_SIZE')) {
+            /**
+             * This is the buffer size for fread/fgets operations (default 4096)
+             * Define BUFFER_SIZE before instantiation to use a different size
+             */
+            define('BUFFER_SIZE', 4096);
+        }
+        $vars_array = is_array($vars) ? $vars : array();
+        $initial_vars = $this -> set_initial_vars($vars_array);
+        //$this -> debug($initial_vars);
+        $this -> sock_connect($initial_vars);
+        $initial_output = $this -> sock_get();
+        if ($initial_output['Content-Type'] == 'auth/request') {
+            $this -> debug('---- authentication requested ----');
+            $this -> sock_auth($initial_vars['pass']);
+        }
+    }
+
+    /**
+     * Close the connection to the event socket
+     *
+     */
+    function sock_close() {
+        $this -> send_command('exit');
+        fclose($this -> sock);
+    }
+
+    /**
+     * Sets connection info from array passed, or used a set of defaults if nothing is passed
+     *
+     * @param array $var_array array of connection settings to use (host|port|pass|timeout)
+     * @return array
+     */
+    function set_initial_vars($var_array) {
+        $defaults = array(
+        'host' => '127.0.0.1',
+        'port' => '8021',
+        'pass' => 'ClueCon',
+        'timeout' => 30,
+        'stream_timeout' => 5
+        );
+        if (array_key_exists('host', $var_array)
+        && $var_array['host'] == 'localhost') {
+            //$this -> debug('Replacing localhost with 127.0.0.1');
+            $var_array['host'] = '127.0.0.1';
+        }
+        foreach ($defaults as $key => $val) {
+            if (array_key_exists($key, $var_array)) {
+                //$this -> debug("$key found in vars");
+                $connection_settings[$key] = $var_array[$key];
+            } else {
+                //$this -> debug("$key not found in vars");
+                $connection_settings[$key] = $val;
+            }
+        }
+        //$this -> debug($connection_settings);
+        return $connection_settings;
+    }
+
+    /**
+     * Connect to the event socket using the array determined by set_initial_vars
+     *
+     * @param array $sock_array array of connection parameters
+     * @return boolean
+     */
+    function sock_connect($sock_array) {
+        //$this -> debug($sock_array);
+        $host = $sock_array['host'];
+        $port = $sock_array['port'];
+        $timeout = $sock_array['timeout'];
+        $this -> sock = fsockopen($host, $port, $errno, $errstr, $timeout);
+        if (!$this -> sock) {
+            $error = sprintf('Unable to connect to %s:%s Error #%s: %s'
+            , $host, $port, $errno, $errstr
+            );
+            trigger_error($error, E_USER_ERROR);
+            return false;
+        } else {
+            //$this -> debug(stream_get_meta_data($this -> sock));
+            $this -> set_stream_opts($sock_array);
+            return true;
+        }
+    }
+
+    /**
+     * Set the stream timeout to not block for long periods of time
+     *
+     * @param array $opts initial options passed to class instantiation
+     * @return void
+     */
+    function set_stream_opts($opts) {
+        //$this -> debug($opts);
+        if (ereg('^[0-9]*\.[0-9]+$', $opts['stream_timeout'])) {
+            //$this -> debug($opts['stream_timeout'] . ' seems to be a float');
+            $time_opts = split('\.', $opts['stream_timeout']);
+            //$this -> debug($time_opts);
+            $secs = sprintf('%d', $time_opts[0]);
+            $ms = ($time_opts[1] * 100000);
+        } else {
+            $secs = $opts['stream_timeout'];
+            $ms = 0;
+        }
+        if (!stream_set_timeout($this -> sock, $secs, $ms)) {
+            $this -> debug(
+            "Failed to set timeout to $secs seconds and $ms microseconds"
+            );
+        }
+    }
+
+    /**
+     * Authenticate to the FreeSWITCH event socket
+     *
+     * @param string $pass FreeSWITCH event socket password
+     * @return void
+     */
+    function sock_auth($pass) {
+        $reply = $this -> send_command("auth $pass");
+        if (is_array($reply) && array_key_exists('Reply-Text', $reply)
+        && ereg('^\+?OK', $reply['Reply-Text'])) {
+            $this -> debug('Successfully authenticated');
+            $this -> debug($reply);
+            $this -> auth = true;
+        } else {
+            $this -> debug('Failed to authenticate');
+            $this -> debug($reply);
+            $this -> auth = false;
+        }
+    }
+
+    /**
+     * write raw data to the FreeSWITCH socket
+     *
+     * @param string $input command to write to the socket
+     */
+    private function sock_put($input) {
+        fputs($this -> sock, $input);
+    }
+
+    /**
+     * Read an event from the FreeSWITCH event socket
+     *
+     * @return array multi-dimentional array of the event
+     */
+    private function sock_get() {
+        $this -> debug('----   Event Start ----');
+        while ($orig_line = fgets($this -> sock, BUFFER_SIZE)) {
+            $trim_line = trim($orig_line);
+            $this -> debug($trim_line);
+            if (strlen($trim_line) > 0) {
+                if (strstr($trim_line, ":")) {
+                    $split = split(":", $trim_line);
+                    $header = trim($split[0]);
+                    $value = trim($split[1]);
+                    $event[$header] = $value;
+                }
+            } elseif (is_array($event)
+            && array_key_exists('Content-Length', $event)) {
+                $this -> debug("line is empty: " . (empty($trim_line) ? 'true' : 'false'));
+                $event['Body'] = $this -> sock_get_length($event['Content-Length']);
+                break;
+            } else {
+                break;
+            }
+        }
+        $this -> debug('----   Event Finish ----');
+        $this -> debug($event);
+        return $event;
+    }
+
+    /**
+     * Read $content_len bytes from the socket
+     *
+     * @param integer $content_len
+     * @return array
+     */
+    private function sock_get_length($content_len) {
+        $this -> debug("calling sock_get_length with length of $content_len");
+        //for ($i=0; $i<$content_len; $i+=strlen($orig_line)) {
+        while ($orig_line = fgets($this -> sock, BUFFER_SIZE)) {
+            $len += strlen($orig_line);
+            $trim_line = trim($orig_line);
+            $this -> debug("$trim_line - $len");
+            if (strstr($orig_line, ":")) {
+                $split = split(":", $orig_line);
+                $attribute = trim($split[0]);
+                $value = trim($split[1]);
+                $content[$attribute] = urldecode($value);
+            } elseif (empty($trim_line) && is_array($content)
+            && array_key_exists('Content-Length', $content)) {
+                $content['Body'] = $this -> sock_get_length($content['Content-Length']);
+                $len += $content['Content-Length'];
+                break;
+            } elseif (!empty($trim_line)) {
+                $content .= $trim_line;
+            }
+            if ($len >= $content_len) {
+                break;
+            }
+        }
+        $this -> debug("leaving after $len bytes");
+        //$this -> debug($content);
+        return $content;
+    }
+
+    /**
+     * Send a command to the FreeSWITCH event socket
+     * This method sends a command string to the FreeSWITCH event socket and
+     * returns true upon success and false upon failure
+     * @param string $cmd command string to send to socket excluding any \r or \n
+     * @return boolean
+     */
+    public function send_command($cmd) {
+        $this -> debug('command is ' . $cmd);
+        $cmd_split = split(' ', $cmd);
+        //$this -> debug($cmd_split);
+        $this -> command = $cmd_split[0];
+        if ($this -> auth != true && $this -> command != 'auth') {
+            unset($this -> command);
+            return false;
+        }
+        $this -> debug("sending command: '$cmd'");
+        $this -> sock_put("$cmd\r\n\r\n");
+        if ($this -> command != 'exit') {
+            $reply = $this -> sock_get();
+            //$this -> debug($reply);
+        } else {
+            unset($this -> command);
+            return;
+        }
+        if (is_array($reply)) {
+            unset($this -> command);
+            return $reply;
+        } else {
+            unset($this -> command);
+            $this -> debug("Didn't get an array as a reply");
+            return false;
+        }
+    }
+
+    /**
+     * Execute an api command
+     *
+     * @param string $cmd_str
+     * @return array of the response or false
+     */
+    function api_command($cmd_str) {
+        $reply = $this -> send_command("api $cmd_str");
+        while ($reply['Content-Type'] != 'api/response') {
+            if (count($reply) > 0) {
+                $debug_text = sprintf(
+                "%s - (%s) != (api/response) adding an event to the output buffer"
+                , count($reply), $reply['Content-Type']
+                );
+                $this -> debug($debug_text);
+                $this -> output_buffer[] = $reply;
+            }
+            $reply = $this -> sock_get();
+        }
+        return $reply;
+    }
+
+    /**
+     * Execute a backgrounded api command
+     *
+     * @param string $cmd_str
+     * @return array of the response or false
+     */
+    function bgapi_command($cmd_str) {
+        $reply = $this -> send_command("bgapi $cmd_str");
+        while ($reply['Content-Type'] != 'command/reply') {
+            if (count($reply) > 0) {
+                $debug_text = sprintf(
+                "%s - (%s) != (command/reply) adding an event to the output buffer"
+                , count($reply), $reply['Content-Type']
+                );
+                $this -> debug($debug_text);
+                $this -> output_buffer[] = $reply;
+            }
+            $reply = $this -> sock_get();
+        }
+        if (array_key_exists('Reply-Text', $reply)) {
+            $split = split(':', $reply['Reply-Text']);
+            $uuid = trim($split[1]);
+            $reply['Job-UUID'] = $uuid;
+        }
+        return $reply;
+    }
+
+    /**
+     * Pop an event off of the buffer or try to get one from the socket
+     *
+     * @return array
+     */
+    function read_event() {
+        if (count($this -> output_buffer) > 0) {
+            return array_shift($this -> output_buffer);
+        } else {
+            $reply = $this -> sock_get();
+            return $reply;
+        }
+    }
+
+    /**
+     * Keep trying read_event until we actually get one
+     *
+     * @return array
+     */
+    function wait_for_event() {
+        $event = array();
+        while (count($event) < 1) {
+        	$event = $this -> read_event();
+        }
+        return $event;
+    }
+
+    /**
+     * Subscribe to event notifications
+     *
+     * @param mixed $events comma-separated or array of events
+     * @return boolean
+     */
+    function subscribe_events($events) {
+        if (is_array($events)) {
+            if (count($events) > 1) {
+                $events_str = implode(',', $events);
+            } else {
+                $events_str = $events[0];
+            }
+        } else {
+            $events_str = $events;
+        }
+        $reply = $this -> send_command("event plain $events_str");
+        $this -> debug($reply);
+        if (ereg('^\+?OK', $reply['Reply-Text'])) {
+            return true;
+        } else {
+            return false;
+        }
+    }
+
+    /**
+     * Function to print out debugging info
+     * This method will recieve arbitrary data and print it to the screen
+     * enable/disable by defining FS_SOCK_DEBUG to true/false
+     * @param mixed $input what to debug, arrays and strings tested, objects MAY work
+     * @param integer $spaces
+     */
+    function debug($input, $spaces=0) {
+        if (defined('FS_SOCK_DEBUG') && FS_SOCK_DEBUG == true) {
+            if (is_array($input)) {
+                foreach ($input as $key=>$val) {
+                    if (is_array($val) || is_object($val)) {
+                        $this -> debug("[$key] => $val", $spaces+4);
+                        $this -> debug('(', $spaces + 8);
+                        $this -> debug($val, $spaces + 8);
+                    } else {
+                        $this -> debug("[$key] => '$val'", $spaces + 4);
+                    }
+                }
+                $this -> debug(")", $spaces);
+            } else {
+                if (is_array($_SERVER)
+                && array_key_exists('HTTP_HOST', $_SERVER)) {
+                    printf("<pre>%s%s</pre>\r\n"
+                    , str_repeat(' ', $spaces)
+                    , htmlentities($input)
+                    );
+                } else {
+                    $input = trim($input);
+                    printf("%s%s\r\n", str_repeat(' ', $spaces), $input);
+                }
+            }
+        }
+    }
+}
+?>
\ No newline at end of file

Added: freeswitch/trunk/scripts/contrib/intralanman/PHP/fs_sock/socktest.php
==============================================================================
--- (empty file)
+++ freeswitch/trunk/scripts/contrib/intralanman/PHP/fs_sock/socktest.php	Tue Jan  8 16:55:23 2008
@@ -0,0 +1,62 @@
+<?php
+require_once('fs_sock.php');
+
+// uncommenting this will produce LARGE amounts of output
+// define('FS_SOCK_DEBUG', true);
+
+// different connection settings, all of these should work with a fresh install
+$array[] = array('host'=>'127.0.0.1');
+$array[] = array('host'=>'127.0.0.1', 'port'=>'8021');
+$array[] = array('pass'=>'ClueCon', 'timeout'=>7);
+$array[] = array(
+'host'=>'localhost',
+'port'=>'8021',
+'pass'=>'ClueCon',
+'timeout'=>3,
+'stream_timeout'=>0.5
+);
+
+// commands to run, initially this was how i caught a few of my bugs
+$cmds[] = 'status';
+$cmds[] = 'originate';
+$cmds[] = 'reloadxml';
+$cmds[] = 'invalidapp';
+$cmds[] = 'craptest';
+
+$obj = new fs_sock($array[3]);
+if ($obj -> auth != true) {
+    die(printf("Unable to authenticate\r\n"));
+}
+
+if (!$obj -> subscribe_events('ALL')) {
+    die(printf("Unable to subscribe to events"));
+}
+
+for ($x=0; $x<count($cmds); $x++) {
+    $debug_string = sprintf("Return ouput from (%s) is:", $cmds[$x]);
+    $return = $obj -> api_command($cmds[$x]);
+    $bg_return = $obj -> bgapi_command($cmds[$x]);
+
+    $obj -> debug("$debug_string\r\n");
+    $obj -> debug($return);
+    $obj -> debug($bg_return);
+}
+
+
+
+//get $items number of items from the event buffer
+$output = array();
+$items = 25;
+for ($i=0; count($output)<$items; $i++) {
+    $count = count($output);
+    printf("%s - %s\r\n", $i+1, $count);
+    //$output[] = $obj -> read_event();
+    $output[] = $obj -> wait_for_event();
+}
+$obj -> debug($output);
+
+
+
+
+$obj -> sock_close();
+?>
\ No newline at end of file



More information about the Freeswitch-svn mailing list