Advertisement
Guest User

app_dial ARI implementation

a guest
Feb 5th, 2015
690
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
PHP 9.54 KB | None | 0 0
  1. #!/usr/bin/php -q
  2.  
  3. <?php
  4.    
  5.     /**
  6.      * phpari - A PHP Class Library for interfacing with Asterisk(R) ARI
  7.      * Copyright (C) 2014  Nir Simionovich
  8.      *
  9.      * This library is free software; you can redistribute it and/or
  10.      * modify it under the terms of the GNU Lesser General Public
  11.      * License as published by the Free Software Foundation; either
  12.      * version 2.1 of the License, or (at your option) any later version.
  13.      *
  14.      * This library is distributed in the hope that it will be useful,
  15.      * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16.      * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  17.      * Lesser General Public License for more details.
  18.      *
  19.      * You should have received a copy of the GNU Lesser General Public
  20.      * License along with this library; if not, write to the Free Software
  21.      * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
  22.      * Also add information on how to contact you by electronic and paper mail.
  23.      *
  24.      * Greenfield Technologies Ltd., hereby disclaims all copyright interest in
  25.      * the library `phpari' (a library for creating smart telephony applications)
  26.      * written by Nir Simionovich and its respective list of contributors.
  27.      */
  28.    
  29.     /* DO NOT MODIFY THIS PART, YOU WILL BREAK THIS! */
  30.     $pathinfo = pathinfo($_SERVER['PHP_SELF']);
  31.     $dir = $pathinfo['dirname'] . "/";
  32.     require_once "/opt/lib/php/vendor/autoload.php";
  33.    
  34.    
  35.     /* START YOUR MODIFICATIONS HERE */
  36.    
  37.     class Dial
  38.     {
  39.        
  40.         public $stasisLogger;
  41.         private $ariEndpoint;
  42.         private $stasisClient;
  43.         private $stasisLoop;
  44.         private $phpariObject;
  45.         private $stasisChannelID;
  46.         private $dtmfSequence = "";
  47.         private $channelsObject;
  48.         private $channelStorage = array();
  49.        
  50.         public function __construct($appname = NULL)
  51.         {
  52.             try {
  53.                 if (is_null($appname))
  54.                     throw new Exception("[" . __FILE__ . ":" . __LINE__ . "] Stasis application name must be defined!", 500);
  55.                
  56.                 $this->phpariObject = new phpari($appname, 'phpari.ini');
  57.                
  58.                 $this->ariEndpoint = $this->phpariObject->ariEndpoint;
  59.                 $this->stasisClient = $this->phpariObject->stasisClient;
  60.                 $this->stasisLoop = $this->phpariObject->stasisLoop;
  61.                 $this->stasisLogger = $this->phpariObject->stasisLogger;
  62.                 $this->stasisEvents = $this->phpariObject->stasisEvents;
  63.                
  64.             } catch (Exception $e) {
  65.                 echo $e->getMessage();
  66.                 exit(99);
  67.             }
  68.         }
  69.        
  70.         public function setDtmf($digit = NULL)
  71.         {
  72.             try {
  73.                
  74.                 $this->dtmfSequence .= $digit;
  75.                
  76.                 return TRUE;
  77.                
  78.             } catch (Exception $e) {
  79.                 return FALSE;
  80.             }
  81.         }
  82.        
  83.         // process stasis events
  84.         public function StasisAppEventHandler()
  85.         {
  86.             $this->stasisEvents->on('StasisStart', function ($event) {
  87.                
  88.                 $this->stasisLogger->notice("Event received: StasisStart");
  89.                
  90.                 $args = $event->args;
  91.                 if (isset($args[0])) {
  92.                     $this->stasisChannelID = $event->channel->id;
  93.                     $this->stasisLogger->notice("Creating new instance in channelStorage");
  94.                     $this->stasisLogger->notice("channelStorage: " . print_r($this->channelStorage, TRUE));
  95.                     $this->stasisLogger->notice("About to originate a call to another party, and bridge to us");
  96.                     $response = $this->phpariObject->channels()->channel_originate(
  97.                         $args[0],
  98.                         NULL,
  99.                         array(
  100.                             "app"     => "askme-dial",
  101.                             "appArgs" => '',
  102.                             "timeout" => $args[1]
  103.                         )
  104.                     );
  105.                    
  106.                     /* Creating a Bridge resource */
  107.                     $this->phpariObject->bridges()->create('mixing', 'bridge_' . $response['id']);
  108.                    
  109.                     /* Populate the Storage */
  110.                     $this->channelStorage[$response['id']]['epoch'] = time();
  111.                     $this->channelStorage[$response['id']]['bridge'] = "bridge_" . $response['id'];
  112.                     $this->channelStorage[$response['id']]['A'] = $event->channel->id;
  113.                     $this->channelStorage[$response['id']]['B'] = $response['id'];
  114.                     $this->channelStorage[$event->channel->id]['bridge'] = "bridge_" . $response['id'];
  115.                     $this->channelStorage[$event->channel->id]['B'] = $event->channel->id;
  116.                     $this->channelStorage[$event->channel->id]['A'] = $response['id'];
  117.                    
  118.                     /* Join the bridge */
  119.                     $this->phpariObject->channels()->channel_ringing_start($event->channel->id);
  120.                    
  121.                 } else {
  122.                     $this->stasisLogger->notice("First channel is joinging the bridge: " . $event->channel->id . " -> bridge_" . $response['id']);
  123.                     $this->phpariObject->channels()->channel_ringing_stop($this->channelStorage[$event->channel->id]['A']);
  124.                     $this->phpariObject->channels()->channel_answer($this->channelStorage[$event->channel->id]['A']);
  125.                     $this->phpariObject->bridges()->addchannel($this->channelStorage[$event->channel->id]['bridge'], $this->channelStorage[$event->channel->id]['A']);
  126.                     $this->stasisLogger->notice("Second channel is joining the bridge: " . $event->channel->id . " -> bridge_" . $event->channel->id);
  127.                     $this->phpariObject->channels()->channel_answer($event->channel->id);
  128.                     $this->phpariObject->bridges()->addchannel($this->channelStorage[$event->channel->id]['bridge'], $event->channel->id);
  129.                 }
  130.             });
  131.            
  132.             $this->stasisEvents->on('StasisEnd', function ($event) {
  133.                 /*
  134.                  * The following section will produce an error, as the channel no longer exists in this state - this is intentional
  135.                  */
  136.                 $this->stasisLogger->notice("Event received: StasisEnd");
  137.                 if (isset($this->channelStorage[$event->channel->id])) {
  138.                     $this->stasisLogger->notice("channelStorage: " . print_r($this->channelStorage, TRUE));
  139.                    
  140.                     $this->stasisLogger->notice("Terminating: " . $event->channel->id);
  141.                     $this->phpariObject->channels()->channel_delete($event->channel->id);
  142.                    
  143.                     $this->stasisLogger->notice("Terminating: " . $this->channelStorage[$event->channel->id]['A']);
  144.                     $this->phpariObject->channels()->channel_delete($this->channelStorage[$event->channel->id]['A']);
  145.                    
  146.                     $this->stasisLogger->notice("Terminating: " . $this->channelStorage[$event->channel->id]['bridge']);
  147.                     $this->phpariObject->bridges()->terminate($this->channelStorage[$event->channel->id]['bridge']);
  148.                    
  149.                     unset($this->channelStorage[$this->channelStorage[$event->channel->id]['A']]);
  150.                     unset($this->channelStorage[$event->channel->id]);
  151.                     $this->stasisLogger->notice("channelStorage: " . print_r($this->channelStorage, TRUE));
  152.                 }
  153.             });
  154.         }
  155.        
  156.         public function StasisAppConnectionHandlers()
  157.         {
  158.             try {
  159.                 $this->stasisClient->on("request", function ($headers) {
  160.                     $this->stasisLogger->notice("Request received!");
  161.                 });
  162.                
  163.                 $this->stasisClient->on("handshake", function () {
  164.                     $this->stasisLogger->notice("Handshake received!");
  165.                 });
  166.                
  167.                 $this->stasisClient->on("message", function ($message) {
  168.                     $this->stasisLogger->notice("channelStorage: " . print_r($this->channelStorage, TRUE));
  169.                     $event = json_decode($message->getData());
  170.                     $this->stasisLogger->notice('Received event: ' . $event->type);
  171.                     $this->stasisEvents->emit($event->type, array($event));
  172.                 });
  173.                
  174.             } catch (Exception $e) {
  175.                 echo $e->getMessage();
  176.                 exit(99);
  177.             }
  178.         }
  179.        
  180.         public function execute()
  181.         {
  182.             try {
  183.                 $this->stasisClient->open();
  184.                 $this->stasisLoop->run();
  185.             } catch (Exception $e) {
  186.                 echo $e->getMessage();
  187.                 exit(99);
  188.             }
  189.         }
  190.        
  191.     }
  192.    
  193.     $basicAriClient = new Dial("stasis-dial");
  194.    
  195.     $basicAriClient->stasisLogger->info("Starting Stasis Program... Waiting for handshake...");
  196.     $basicAriClient->StasisAppEventHandler();
  197.    
  198.     $basicAriClient->stasisLogger->info("Initializing Handlers... Waiting for handshake...");
  199.     $basicAriClient->StasisAppConnectionHandlers();
  200.    
  201.     $basicAriClient->stasisLogger->info("Connecting... Waiting for handshake...");
  202.     $basicAriClient->execute();
  203.    
  204.     exit(0);
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement