Giter Site home page Giter Site logo

marcelog / pami Goto Github PK

View Code? Open in Web Editor NEW
396.0 53.0 273.0 6.34 MB

PHP Asterisk Manager Interface ( AMI ) supports synchronous command ( action )/ responses and asynchronous events using the pattern observer-listener. Supports commands with responses with multiple events. Very suitable for development of operator consoles and / or asterisk / channels / peers monitoring through SOA, etc

Home Page: http://marcelog.github.com/PAMI

License: Apache License 2.0

PHP 100.00%
asterisk ami php

pami's Introduction

License Latest Stable Version Documentation Status

Build Status Coverage Status Code Climate Issue Count

![Click here to lend your support to: PAMI and make a donation at pledgie.com !](https://pledgie.com/campaigns/30944.png?skin_name=chrome' border='0')

Introduction

PAMI means PHP Asterisk Manager Interface. As its name suggests its just a set of php classes that will let you issue commands to an ami and/or receive events, using an observer-listener pattern.

The idea behind this, is to easily implement operator consoles, monitors, etc. either via SOA or ajax.

A port for nodejs is available at: http://marcelog.github.com/Nami A port for erlang is available at: https://github.com/marcelog/erlami

Resources

PHP Versions

Note: PAMI Requires PHP 5.3+. PHP versions 5.3.9 and 5.3.10 WILL NOT WORK due to a bug introduced in stream_get_line() in 5.3.9. Please use 5.3.11+ or up to 5.3.8 (see README.PHP-5.3.9-and-5.3.10).

Installing

Add this library to your Composer configuration. In composer.json:

  "require": {
    "marcelog/pami": "2.*"
  }

QuickStart

For an in-depth tutorial: http://marcelog.github.com/articles/pami_introduction_tutorial_how_to_install.html

// Make sure you include the composer autoload.
require __DIR__ . '/vendor/autoload.php';

$options = array(
    'host' => '2.3.4.5',
    'scheme' => 'tcp://',
    'port' => 9999,
    'username' => 'asd',
    'secret' => 'asd',
    'connect_timeout' => 10,
    'read_timeout' => 10
);
$client = new \PAMI\Client\Impl\ClientImpl($options);

// Registering a closure
$client->registerEventListener(function ($event) {
});

// Register a specific method of an object for event listening
$client->registerEventListener(array($listener, 'handle'));

// Register an IEventListener:
$client->registerEventListener($listener);

Using Predicates

A second (optional) argument can be used when registering the event listener: a closure that will be evaluated before calling the callback. The callback will be called only if this predicate returns true:

use PAMI\Message\Event\DialEvent;

$client->registerEventListener(
    array($listener, 'handleDialStart'),
    function ($event) {
        return $event instanceof DialEvent && $event->getSubEvent() == 'Begin';
    })
);

Example

Please see docs/examples/quickstart/example.php for a very basic example.

AsterTrace is a full application: https://github.com/marcelog/AsterTrace.

Also, you might want to look at this article: http://marcelog.github.com/articles/php_asterisk_listener_example_using_pami_and_ding.html

For an example of using asynchronous AGI with PAMI, see docs/examples/asyncagi

The march edition of Software Developer Journal features a complete article about writing telephony applications with PAMI and PAGI.

Currently Supported Events

More events will be added with time. I can only add the ones I can test for and use, so your contributions may make the difference! ;)

Unknown (not yet implemented) events will be reported as UnknownEvent, so you can still catch them. If you catch one of these, please report it!

  • AgentsComplete
  • AgentConnect
  • Agentlogin
  • Agentlogoff
  • AGIExec
  • AsyncAGI
  • Bridge
  • BridgeInfoChannel
  • BridgeInfoComplete
  • CEL
  • ChannelUpdate
  • ConfbridgeEnd
  • ConfbridgeJoin
  • ConfbridgeLeave
  • ConfbridgeList
  • ConfbridgeListComplete
  • ConfbridgeMute
  • ConfbridgeStart
  • ConfbridgeTalking
  • ConfbridgeUnmute
  • CoreShowChannel
  • CoreShowChannelComplete
  • DAHDIShowChannel
  • DAHDIShowChannelsComplete
  • FullyBooted
  • DongleSMSStatus
  • DongleUSSDStatus
  • DongleNewUSSD
  • DongleNewUSSDBase64
  • DongleNewCUSD
  • DongleStatus
  • DongleDeviceEntry
  • DongleShowDevicesComplete
  • DBGetResponse
  • Dial
  • DTMF
  • Extension
  • Hangup
  • Hold
  • JabberEvent
  • Join
  • Leave
  • Link
  • ListDialplan
  • Masquerade
  • MessageWaiting
  • MusicOnHold
  • NewAccountCode
  • NewCallerid
  • Newchannel
  • Newexten
  • Newstate
  • OriginateResponse
  • ParkedCall
  • ParkedCallsComplete
  • PeerEntry
  • PeerlistComplete
  • PeerStatus
  • QueueMember
  • QueueMemberAdded
  • QueueMemberRemoved
  • QueueMemberPause
  • QueueMemberStatus
  • QueueParams
  • QueueStatusComplete
  • QueueSummaryComplete
  • RegistrationsComplete
  • Registry
  • Rename
  • RTCPReceived
  • RTCPReceiver
  • RTCPSent
  • RTPReceiverStat
  • RTPSenderStat
  • ShowDialPlanComplete
  • Status
  • StatusComplete
  • Transfer
  • Unlink
  • UnParkedCall
  • UserEvent
  • VarSet
  • vgsm_me_state
  • vgsm_net_state
  • vgsm_sms_rx
  • VoicemailUserEntry
  • VoicemailUserEntryComplete

Currently Supported Actions

  • AbsoluteTimeout
  • AGI
  • Agents
  • AgentLogoff
  • Atxfer (asterisk 1.8?)
  • Bridge
  • BridgeInfo
  • ChangeMonitor
  • Command
  • ConfbridgeList
  • ConfbridgeMute
  • ConfbridgeUnmute
  • CoreSettings
  • CoreShowChannels
  • CoreStatus
  • DAHDIDialOffHookAction
  • DAHDIHangup
  • DAHDIRestart
  • DAHDIShowChannels
  • DAHDIDNDOn
  • DAHDIDNDOff
  • DBGet
  • DBPut
  • DBDel
  • DBDelTree
  • DongleSendSMS
  • DongleSendUSSD
  • DongleSendPDU
  • DongleReload
  • DongleStop
  • DongleStart
  • DongleRestart
  • DongleReset
  • DongleShowDevices
  • ExtensionState
  • CreateConfig
  • GetConfig
  • GetConfigJSON
  • GetVar
  • Hangup
  • JabberSend
  • LocalOptimizeAway
  • Login
  • Logoff
  • ListCategories
  • ListCommands
  • MailboxCount
  • MailboxStatus
  • MeetmeList
  • MeetmeMute
  • MeetmeUnmute
  • MixMonitor
  • ModuleCheck
  • ModuleLoad (split in ModuleLoad, ModuleUnload, and ModuleReload)
  • Monitor
  • Originate
  • ParkedCalls
  • PauseMonitor
  • Ping
  • PlayDTMF
  • Queues
  • QueueAdd
  • Queue
  • QueueLog
  • QueuePause
  • QueuePenalty
  • QueueReload
  • QueueRemove
  • QueueReset
  • QueueRule
  • QueueSummary
  • QueueStatus
  • QueueUnpause
  • Redirect
  • Reload
  • SendText
  • SetVar
  • ShowDialPlan
  • Sipnotify
  • Sippeers
  • Sipqualifypeer
  • Sipshowpeer
  • Sipshowregistry
  • Status
  • StopMixMonitor
  • StopMonitor
  • UnpauseMonitor
  • VGSM_SMS_TX
  • VoicemailUsersList

Debugging, logging

You can optionally set a PSR-3 compatible logger:

$pami->setLogger($logger);

By default, the client will use the NullLogger.

Developers

This project uses phing. Current tasks include:

Running a phing task

To run a task, just do:

vendor/bin/phing build

Contributing

To contribute:

  • Make sure you open a concise and short pull request.
  • Throw in any needed unit tests to accomodate the new code or the changes involved.
  • Run phing and make sure everything is ok before submitting the pull request (make phpmd and CodeSniffer happy, also make sure that phpDocumentor does not throw any warnings, since all our documentation is automatically generated).
  • Your code must comply with PSR-2, CodeSniffer should take care of that.

LICENSE

Copyright 2016 Marcelo Gornstein [email protected]

Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

Thanks To

  • Jason Blank for helping in the debugging of the queue functionality and some other ami inconsistencies.

  • Francesco Usseglio Gaudi, for help in debugging the Originate action.

  • Matías Barletta, for the vgms support.

  • Eli Hunter, for helping in bringing in tls compatibility.

  • Freddy dafredmail at googlemail, for his help and testing environment to add dongle support.

  • Joshua Elson for his help in trying and debugging in loaded asterisk servers.

  • Jacob Kiers for his help in bringing in and testing async agi functionality, and CEL event support.

  • Richard Baar for noticing the lack of eof support when reading from socket, the JabberEvent, and the ScreenName in JabberAction.

  • Scot Opell for helping in debugging stream_get_line() in 5.3.9 and 5.3.10

  • Brian (wormling) for trying and fixing bugs on asyncagi

  • Henning Bragge for helping with newstate event and queues.

  • mbonneau for ParkedCall and UnParkedCall events.

pami's People

Contributors

almogbaku avatar cch99 avatar drakhar-mike avatar jacobkiers avatar marcelog avatar mstyles avatar pkirk avatar quosimadu avatar richardfullmer avatar shinomontaz avatar strikeforcezero avatar thomasvargiu avatar tomcastleman avatar wormling avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

pami's Issues

Bind to specific kinds of events

Hello.
Is it possible for PAMI to bind JUST to PeerStatus events?

I know for sure i can bind to (EventMessage $event) using a handler function, and then use getName() to filter for "PeerStatus events...

... but i would not like to waste CPU listening to every single event on the AMI if the library has implemented this on a lower level.

I´m currently using:

public function handle(EventMessage $event)
    {
        if($event->getName() == "PeerStatus"){
                if($event->getKey("peerstatus") == "Rejected"){
                        $ip = $event->getKey("address");
                        $this->ips["$ip"] += 1;
                        echo "IP $ip has ".$this->ips["$ip"]." Failed Attempts\n";
                        if($this->ips["$ip"] > 30){
                                //Ban IP
                                if($this->ips["$ip"] != 10000){
                                        $res = shell_exec("/sbin/ipset add blacklist $ip");
                                        $this->ips["$ip"] = 10000;
                                }
                        }

                        //Flush object once in a while
                        if(size($this->ips["$ip"]) > 1024){
                                $this->ips["$ip"] = array();
                        }

                }
        }

    }

As you see.. i´m tired of relying on fail2ban and i implemented my own "Anti-Dictionary attack" code.. which directly BLOCKS every IP that fails to register 30 times using IPSET and IPTABLES,

Best
pedro

problem with PHP 5.3.10

I've tried to make an "Originate" Action using PAMI using PHP5.3.10, it doesn't work.

I fixed it downgrading my PHP to 5.3.8

Is it me or PAMI isn't compatible with PHP 5.3.10 ?

Thanks

result in variable

Hi,
i just started using your PAMI. i can see Events and Actions results on screen. how can i save events and actions result in variable and save them in DB. is there any discussion form of PAMI?

Thanks

missing event: Leave

event: Leave
privilege: call,all
channel: Local/5001@from-internal-61a6;2
queue: 5001
count: 0
uniqueid: 1301942099.1324731

Action CoreShowChannel does not work correctly with sip channels

it seems that asterisk (or chan_sip) is not sending the response in the right way. for dahdi channels, a response with eventlist: start followed by events and terminated by an eventlist: complete is sent.

for sip channels, the events DO NOT HAVE the Event: and neither the ActionId: and EventList: options. I'll try to fill a bug report with digium about this

AsyncClientImpl send hang

I noticed that when I hang up my sip client just before my Async AGI application calls something like consoleLog, the process would hang forever in send() due to while($this->_lastAgiResult === false) {... which will always be false in this case.

See wormling@fa92fa4 for an example solution. I think maybe pass a timeout option to the constructor and use that like you've done in ClientImpl may be cleaner though. If you give me a suggestion, I could submit a PR for this.

DialEvent in asterisk 11.10 not found?

Hi,

I'm just starting to try PAMI. Thank you so much for this amazing piece of code.

basically I followed your sample code on returning
$event instanceof DialEvent

however it does not return Dial events.

returning ALL events shows a dial as:

object(PAMI\Message\Event\DialEvent)#8 (6) {
  ["rawContent":protected]=>
  string(357) "Event: Dial
Privilege: call,all
SubEvent: Begin
Channel: Local/725@agents-00002e41;2
Destination: SIP/725-00005809
CallerIDNum: 256197189
CallerIDName: Cabovisao:0:256197189:1458856633.46235:SIP/fundao-pstn-00005806
ConnectedLineNum: 275759144
ConnectedLineName: <unknown>
UniqueID: 1458856646.46238
DestUniqueID: 1458856647.46240
Dialstring: 725"
  ["channelVariables":protected]=>
  array(1) {
    ["local/725@agents-00002e41;2"]=>
    array(0) {
    }
...

Why is it not returned as a DialEvent ? Is this different from 1.6 or 1.8 ?

Use PSR-3 dependency for logger instead of log4php

Now when there is a PSR-3 standard for logging with php, maybe the hard dependency on log4php could be replaced with a dependency on Psr\Log\LoggerInterface instead of a specific logging library.

This would allow to use any other logging library, for example Monolog etc.

Some related links:
http://www.php-fig.org/psr/psr-3/
http://www.sitepoint.com/logging-with-psr-3-to-improve-reusability/
http://www.sitepoint.com/implementing-psr-3-with-log4php/

Would a PR for this be accepted? Is anything like this already being worked on?

AgentsEvent return is missing a proper end of line when agent in use

Hello, while using PAMI i run at a problem where LoggedInTime of an agent disapear when in use, while digging i found that the event returned from the manager having the line CallStarted without a proper end of line.

Event: Agents\r\n
Agent: agent_doe\r\n
Name: Jhon Doe\r\n
Status: AGENT_ONCALL\r\n
TalkingToChan: SIP/1010-00000073\r\n
CallStarted: 1443613421\n
LoggedInTime: 1443608760\r\n
Channel: SIP/1234-00000060\r\n
...

I know it is probably a module side issue, but i wanted to put it as a heads up, while also digging for a work around since events classes are hard coded into the package

Incorrect EOF test in getMessages

In ClientImpl::getMessages there is an icorrect EOF test:
if ($read === false || feof($this->_socket)) {
the correct one should look like:
if ($read === false || (strlen($read) == 0 && @Feof($this->_socket))) {

I found this one having occassional read exceptions during a logoff command. The problem
somehow relates to the fact, that fread can return data, but later feof test signals end of file condition.
Therefore feof should be tested only if fread returns an empty string, which means there is no data, an end of file has been reached or some other error occured.

Read Timeout

Hello,

I'm trying to run the quickstart example, but I allways get - read timeout after a minute of loading of example.php.

I'm working on Centos 5.6, with PHP 5.3 and log4php installed... I see that the script tries to connect to AMI, but no success:

Asterisk cli:

== Client from 127.0.0.1, failed to authenticate in 30 seconds

log.log:

*----------
2012-02-27 19:58:24,001 [DEBUG] Pami.ClientImpl: ------ Sending: ------
action: Login
actionid: 1330369073.3835
username: test
secret: test123


2012-02-27 20:02:26,001 [DEBUG] Pami.ClientImpl: ------ Sending: ------
action: Login
actionid: 1330369315.1347
username: test
secret: test123

----------*

example.php (changed parts):

date_default_timezone_set("Europe/Berlin");
set_include_path('/var/www/html/test/PAMI/log4php');
// Setup include path.
ini_set(
'include_path',
implode(
PATH_SEPARATOR,
array(
implode(DIRECTORY_SEPARATOR, array('..', '..', '..', 'src', 'mg')),
ini_get('include_path'),
)
)
);
.
.
.
.
try
{
$options = array(
'log4php.properties' => realpath(DIR) . DIRECTORY_SEPARATOR . 'log4php.properties',
'host' => 'localhost',
'port' => '5038',
'username' => 'test',
'secret' => 'test123',
'connect_timeout' => 10000,
'read_timeout' => 10000,
'scheme' => 'tcp://' // try tls://
);

Manager.conf has the correct entry's for user test.

How can I debug, where is the problem with the too long loading?

Connection error in PAMI

I am using PAMI for asterisk manager.I am totally new to this.Here is my code

error_reporting(E_ALL);
ini_set('display_errors', 1);

use PAMI\Client\Impl\ClientImpl as PamiClient;
require_once 'PAMI/Autoloader/Autoloader.php';
PAMI\Autoloader\Autoloader::register();

$pamiClientOptions = array(
'host' => '127.0.0.1',
'scheme' => 'tcp://',
'port' => 5038,
'username' => 'tarunM',
'secret' => 'f713cea2065d94f9b942c97c1b8caacf',
'connect_timeout' => 10000,
'read_timeout' => 10000
);

$pamiClient = new PamiClient($pamiClientOptions);

// Open the connection
$pamiClient->open();

use PAMI\Message\Event\EventMessage;
use PAMI\Message\Event\DialEvent;

$pamiClient->registerEventListener(function (EventMessage $event) {
print_r($event);
},
function ($event) {
$re = $event instanceof DialEvent && $event->getDialStatus() == 'ANSWER';
if ($re){
echo "Found Event\n";
global $pamiClient;
$pamiClient->close();
}
}
);

$running = true;

while($running) {
$pamiClient->process();
usleep(1000);
}

echo "Code Ended>>>>>>>>>>>>>>>>>>> Read This Line\n";

it is showing this error
DEBUG - ------ Sending: ------ action: Login actionid: 1457504735.3649 username: tarunM secret: f713cea2065d94f9b942c97c1b8caacf ---------- Fatal error: Uncaught exception 'PAMI\Client\Exception\ClientException' with message 'Error reading' in /usr/share/pear/PAMI/Client/Impl/ClientImpl.php:236 Stack trace: #0 /usr/share/pear/PAMI/Client/Impl/ClientImpl.php(258): PAMI\Client\Impl\ClientImpl->getMessages() #1 /usr/share/pear/PAMI/Client/Impl/ClientImpl.php(410): PAMI\Client\Impl\ClientImpl->process() #2 /usr/share/pear/PAMI/Client/Impl/ClientImpl.php(181): PAMI\Client\Impl\ClientImpl->send(Object(PAMI\Message\Action\LoginAction)) #3 /var/www/html/AMI/PAMI-master/index.php(22): PAMI\Client\Impl\ClientImpl->open() #4 {main} thrown in /usr/share/pear/PAMI/Client/Impl/ClientImpl.php on line 236

missing QueueMemberRemoved event

event: QueueMemberRemoved
privilege: agent,all
queue: 1234
location: Local/7279@from-queue/n
membername: Local/7279@from-queue/n

Support for ChanVariable(channel): MY_VAR=value

In Asterisk manager.conf the channelvars option exists:

;
; Display certain channel variables every time a channel-oriented
; event is emitted:
;
;channelvars = var1,var2,var3

So if one would define channelvars = var1,var2,var3 you would get the following appended to all channel-oriented events:

ChanVariable(SIP/jw9933-00000062): var1=14
ChanVariable(SIP/jw9933-00000062): var2=value-of-var2
ChanVariable(SIP/jw9933-00000062): var3=value-of-var3

However, PAMI doesn't understand this syntax and you end up with only one key ChanVariable(SIP/jw9933-00000062) that has the value var3=value-of-var3 as var1 and var2 is overwritten.

So I have this (quite ugly I know) code to parse it for now:

    /**
     * @return array
     */
    protected function getChannelVariables(\PAMI\Message\Event\EventMessage $event)
    {
        $channel_vars = array();
        $channel_id = $event->getKey('Channel');

        // we can't get the variables if we doesn't have a channel
        if ($channel_id === null)
            return $channel_vars;

        $prefix = "ChanVariable(" . $channel_id . "):";
        $length = strlen($prefix);
        $rows = explode("\n", $event->getRawContent());
        foreach ($rows as $row)
            if (substr($row, 0, $length) == $prefix)
            {
                list($chanvar, $data) = explode('=', substr($row, $length));
                $channel_vars[trim($chanvar)] = trim($data);
            }
        return $channel_vars;
    }

There actually could be variables for different channels in some cases, but I don't use it right now so the above code doesn't support that.

I would like to have a more clean way of doing this. Some proposals:

  • If a key exists more than once during parsing, put them in an array so we don't overwrite values
  • Add a getChannelVariables($channel = null) helper to the base-class (EventMessage?) that parses the values and return them for the given channel. If no channel is specified then we merge the variables for all channels.
  • Maybe also add a getChannelVariable($channel, $key) that only looks for one specific key.
  • Another way?

I can implement this and make a PR if I this will be accepted as a contribution.

Thanks for a great library by the way!

PAMI Documentation

Hi,
is there any PAMI Documentation available, which describe the events, shows how to use events and how to get some specific events values and save them in DB. Thanks.

PAMI Disconnect‏

Hi,
I am using PAMI to get Asterisk Manager Events. please see my code below. I wanted to get $event->getDialStatus() = 'ANSWER' of Dial Event and as i get result disconnect the Asterisk Manager and read the remaining code. Thanks.

'127.0.0.1', 'scheme' => 'tcp://', 'port' => 5038, 'username' => 'ncs', 'secret' => 'ncs', 'connect_timeout' => 10000, 'read_timeout' => 10000 ); $pamiClient = new PamiClient($pamiClientOptions); // Open the connection $pamiClient->open(); use PAMI\Message\Event\EventMessage; use PAMI\Message\Event\DialEvent; $pamiClient->registerEventListener(function (EventMessage $event) { print_r($event); }, function ($event) { ``` $re = $event instanceof DialEvent && $event->getDialStatus() = 'ANSWER'; ``` if ($re){ echo "Found Event\n"; } } ); $running = true; while($running) { $pamiClient->process(); usleep(1000); } // Close the connection # $pamiClient->close(); echo "Code Ended>>>>>>>>>>>>>>>>>>> Read This Line\n"; ?>

Parse asterisk's "core-en_US.xml" file to get all the manager function + parameter definitions

How about using the /var/lib/asterisk/documentation/core-en_US.xml file which the asterisk make process generates automatically since asterisk-1.8. It will provide you with all the manager functions for that asterisk version including the parameter it accept. After parsing it once, you only have to verify if the timestamp on that files has changed. It should make 90-95% available and only require manual intervention for some quirky Message and the few external channel drivers like chan-sccp-b chan-dongle chan-lcr etc. If you like you could persuade them to produce a similar file (i would be willing to do this for the chan-sccp-b project would if so requested).

The content of that files looks like:

        <manager name="MixMonitorMute" language="en_US">
                <synopsis>
                        Mute / unMute a Mixmonitor recording.
                </synopsis>
                <syntax>
                        <xi:include xpointer="xpointer(/docs/manager[@name='Login']/syntax/parameter[@name='ActionID'])" />
                        <parameter name="Channel" required="true">
                                <para>Used to specify the channel to mute.</para>
                        </parameter>
                        <parameter name="Direction">
                                <para>Which part of the recording to mute:  read, write or both (from channel, to channel or both channels).</para>
                        </parameter>
                        <parameter name="State">
                                <para>Turn mute on or off : 1 to turn on, 0 to turn off.</para>
                        </parameter>
                </syntax>
                <description>
                        <para>This action may be used to mute a MixMonitor recording.</para>
                </description>
        </manager>

Which should be pretty easy to parse using php. Is't just a suggestion, possibly saving you a lot of maintenance work

Incorrect CommandAction response

PAMI incorrectly parses Command core show hints response:

object(PAMI\Message\Response\ResponseMessage)#57 (9) {
  ["_events":"PAMI\Message\Response\ResponseMessage":private]=>
  array(0) {
  }
  ["_completed":"PAMI\Message\Response\ResponseMessage":private]=>
  bool(true)
  ["rawContent":protected]=>
  string(3227) "Response: Follows
Privilege: Command
ActionID: 1442565050.0953

    -= Registered Asterisk Dial Plan Hints =-
                   2601@status              : SIP/2601              State:Idle            Watchers  9
                   2602@status              : SIP/2602              State:Unavailable     Watchers 10
                   2803@status              : SIP/2803              State:Unavailable     Watchers  9
                   2802@status              : SIP/2802              State:Idle            Watchers  9
                  _XXXX@status              : SIP/${EXTEN}          State:Unavailable     Watchers  0
                   2098@status              : SIP/2098              State:Unavailable     Watchers  9
                   9090@status              : SIP/9090              State:Idle            Watchers  8
                   2102@status              : SIP/2102              State:Unavailable     Watchers 10
                   2101@status              : SIP/2101              State:Unavailable     Watchers  9
                   2301@status              : SIP/2301              State:Idle            Watchers 10
                   2302@status              : SIP/2302              State:Unavailable     Watchers  9
                   2005@status              : SIP/2005              State:Unavailable     Watchers  2
                   2004@status              : SIP/2004              State:Unavailable     Watchers 10
                   2003@status              : SIP/2003              State:Idle            Watchers  9
                   2002@status              : SIP/2002              State:Unavailable     Watchers 10
                   2001@status              : SIP/2001              State:Idle            Watchers  9
                   3002@status              : SIP/3002              State:Idle            Watchers  9
                   2502@status              : SIP/2502              State:Unavailable     Watchers 11
                   2503@status              : SIP/2503              State:Unavailable     Watchers 10
                   2501@status              : SIP/2501              State:Unavailable     Watchers 10
                   2201@status              : SIP/2201              State:Unavailable     Watchers  8
                   2203@status              : SIP/2203              State:Unavailable     Watchers  9
                   2202@status              : SIP/2202              State:Idle            Watchers  9
                   2701@status              : SIP/2701              State:Idle            Watchers  8
                   2702@status              : SIP/2702              State:Unavailable     Watchers 10
                   2403@status              : SIP/2403              State:Unavailable     Watchers  9
                   2402@status              : SIP/2402              State:Idle            Watchers  9
                   2401@status              : SIP/2401              State:Unavailable     Watchers 10
                   2902@status              : SIP/2902              State:Unavailable     Watchers  9
                   2901@status              : SIP/2901              State:Idle            Watchers  9
----------------
- 30 hints registered
--END COMMAND--"
  ["channelVariables":protected]=>
  array(1) {
    ["default"]=>
    array(0) {
    }
  }
  ["lines":protected]=>
  array(0) {
  }
  ["variables":protected]=>
  array(0) {
  }
  ["keys":protected]=>
  array(4) {
    ["response"]=>
    string(7) "Follows"
    ["privilege"]=>
    string(7) "Command"
    ["actionid"]=>
    string(15) "1442565050.0953"
    ["-= registered asterisk dial plan hints =-
                   2601@status"]=>
    string(3068) "SIP/2601              State:Idle            Watchers  9
                   2602@status              : SIP/2602              State:Unavailable     Watchers 10
                   2803@status              : SIP/2803              State:Unavailable     Watchers  9
                   2802@status              : SIP/2802              State:Idle            Watchers  9
                  _XXXX@status              : SIP/${EXTEN}          State:Unavailable     Watchers  0
                   2098@status              : SIP/2098              State:Unavailable     Watchers  9
                   9090@status              : SIP/9090              State:Idle            Watchers  8
                   2102@status              : SIP/2102              State:Unavailable     Watchers 10
                   2101@status              : SIP/2101              State:Unavailable     Watchers  9
                   2301@status              : SIP/2301              State:Idle            Watchers 10
                   2302@status              : SIP/2302              State:Unavailable     Watchers  9
                   2005@status              : SIP/2005              State:Unavailable     Watchers  2
                   2004@status              : SIP/2004              State:Unavailable     Watchers 10
                   2003@status              : SIP/2003              State:Idle            Watchers  9
                   2002@status              : SIP/2002              State:Unavailable     Watchers 10
                   2001@status              : SIP/2001              State:Idle            Watchers  9
                   3002@status              : SIP/3002              State:Idle            Watchers  9
                   2502@status              : SIP/2502              State:Unavailable     Watchers 11
                   2503@status              : SIP/2503              State:Unavailable     Watchers 10
                   2501@status              : SIP/2501              State:Unavailable     Watchers 10
                   2201@status              : SIP/2201              State:Unavailable     Watchers  8
                   2203@status              : SIP/2203              State:Unavailable     Watchers  9
                   2202@status              : SIP/2202              State:Idle            Watchers  9
                   2701@status              : SIP/2701              State:Idle            Watchers  8
                   2702@status              : SIP/2702              State:Unavailable     Watchers 10
                   2403@status              : SIP/2403              State:Unavailable     Watchers  9
                   2402@status              : SIP/2402              State:Idle            Watchers  9
                   2401@status              : SIP/2401              State:Unavailable     Watchers 10
                   2902@status              : SIP/2902              State:Unavailable     Watchers  9
                   2901@status              : SIP/2901              State:Idle            Watchers  9
----------------
- 30 hints registered
--END COMMAND--"
  }
  ["createdDate":protected]=>
  int(1442565050)
  ["_eventsCount"]=>
  int(0)
}

As you can see - some part of the response body wa put into key name...
Using latest PAMI release

DongleSendSMSAction send only first line

Hello,
when i try to send multi-lines SMS by DongleSendSMSAction , it's send only first line and ignore other lines .
what i can do to solve this issue ?
$SMS = new DongleSendSMSAction("dongle1", "+10987654321","hello \n Test SMS") ;
Thanks

Logoff action

Logoff action causes exception "Error reading" from file PAMI/Client/Impl/ClientImpl.php in function getMessages.
It is because in

            if ($read === false || feof($this->_socket)) {
                throw new ClientException('Error reading');
            }

feof() is true.
last message from AMI is:

string(83) "Response: Goodbye
ActionID: 1345305085.9158
Message: Thanks for all the fish.

"

please, help me with tha issue.

now I have to do

            try{
                $pamiClient->close();  
            }catch (Exception $e) {}

missing event: MusicOnHold

event: MusicOnHold
privilege: call,all
state: Stop
channel: Local/7166@from-queue-ae79;2
uniqueid: 1301942037.1324689

Complete response event packet not dispatched to client

I was banging my head with a problem where QueueStatusAction did not catch the events related to it.

QueueParams, QueueMember, QueueEntry and QueueStatusComplete events were logged in log4php log file but not sent to client. After checking the process() method in ClientImpl.php I found out that events are added to response but never dispatched to the client.

ClientImpl.php - from line 273

if ($response === false || $response->isComplete()) {
      $this->dispatch($event);
} else {
      $response->addEvent($event);
}

For starters $response->_completed is never set to true so $response->isComplete() is never fired.
But even if the $this->dispatch($event); would fire all the events in $response->_events would never be dispatched to the client, just the latest one.

Am I missing something or is this not implemented?

If needed I can c/p the client code.

Error when trying to exectute autoloader function

It seems like the latest update has broken the library, I've posted additional info below.

PHP version:
PHP 5.1.6 (cli) (built: Nov 29 2010 16:47:37)
Copyright (c) 1997-2006 The PHP Group
Zend Engine v2.1.0, Copyright (c) 1998-2006 Zend Technologies

Error:
PHP Warning: Unexpected character in input: '' (ASCII=92) state=1 in /var/www/html/PAMI/docs/examples/quickstart/example.php on line 50
PHP Warning: Unexpected character in input: '' (ASCII=92) state=1 in /var/www/html/PAMI/docs/examples/quickstart/example.php on line 50
PHP Parse error: syntax error, unexpected T_STRING in /var/www/html/PAMI/docs/examples/quickstart/example.php on line 50

Install via composer is broken for the last version of composer

I used sudo composer self-update to update composer:

Updating to version b808ff5e28944ab2e25e050f8df848c5842bc14c.

Then I tried using composer update and got the following error:

Your requirements could not be resolved to an installable set of packages.

Problem 1
    - Installation request for marcelog/pami dev-master -> satisfiable by marcelog/pami[dev-master].
    - marcelog/pami dev-master requires pear-log4php/apache_log4php >=2.1.0 -> no matching package found.

Potential causes:
 - A typo in the package name
 - The package is not available in a stable-enough version according to your minimum-stability setting
   see <https://groups.google.com/d/topic/composer-dev/_g3ASeIFlrc/discussion> for more details.

So I used sudo composer self-update --rollback to revert the composer version:

Rolling back to version 2014-02-07_09-59-35-7343198.

And the composer update worked normally again.

The setup I'm using on composer.json is the same described on the README:

{
    "require": {
        "marcelog/pami": "dev-master"
    },
    "repositories": [
    {
      "type": "pear",
      "url": "http://pear.apache.org/log4php/"
    }]
}

events action broken

currently broken because asterisk violates -yet again- the ami protocol, not sending the EOM, which is \r\n\r\n

Any suggestions for obtaining extension number dialed at IVR

For example, user calls the main line and presses 1 for sales. I want to some how take note of this and relate it to a call record i'm creating based on Dial Events.

Closest thing that I see is CallerIdNum gets set after user presses numbers on the keypad but the unique id associated with that event isn't the same as the one for the dial event so its hard to relate it to it.

I realize this question may be unfair to ask here. I wouldn't be offended if you close it.

missing QueueMemberAdded event

event: QueueMemberAdded
privilege: agent,all
queue: 1234
location: Local/7279@from-queue/n
membername: Local/7279@from-queue/n
membership: dynamic
penalty: 0
callstaken: 0
lastcall: 0
status: 1
paused: 0

missing event: AgentConnect

event: AgentConnect
privilege: agent,all
queue: 5001
uniqueid: 1301942099.1324731
channel: Local/7001@from-queue-f153;1
member: Local/7001@from-queue/n
membername: Local/7001@from-queue/n
holdtime: 3
bridgedchannel: 1301942099.1324732
ringtime: 3

Read error exception

Hi, Marcelo. I have "Read error" exception throws in ClientImpl->getMessages while calling from one ext to another. It happens on Win Server 2008 R2 with php 5.5.15 (Asterisk is running on my mac virtual FreePBX 6.5 (Parallels Desktop)).

It throws when DialEvent recieved.

Here is my code

use PAMI\Message\Event\LinkEvent;
use PAMI\Message\Event\DialEvent;
use PAMI\Message\Event\HangupEvent;
use PAMI\Message\Event\BridgeEvent;
use PAMI\Message\Event\NewAccountCodeEvent;

$adapter = new AsteriskAdapter(
    $CONFIG['asterisk_host'],
    $CONFIG['asterisk_protocol'],
    $CONFIG['asterisk_port'],
    $CONFIG['asterisk_login'],
    $CONFIG['asterisk_pass']);

if (isset($CONFIG['asterisk_host'], $CONFIG['asterisk_protocol'], $CONFIG['asterisk_port'], $CONFIG['asterisk_login'], $CONFIG['asterisk_pass'])){

    while(true){

        AsteriskAdapter::log("[Asterisk Manager Interface (AMI) Connection]");

        if($adapter->connect()){

            try{
                AsteriskAdapter::log("Successfully conected to {$CONFIG['asterisk_host']}:{$CONFIG['asterisk_port']} as {$CONFIG['asterisk_login']}");

                $adapter->registerCallListener(function(DialEvent $event) use ($adapter){
                    $number = $adapter->getNumber($event->getDestination());
                    $callerId = $event->getCallerIDNum();
                    AsteriskAdapter::log("EVENT: Dial Line: {$number} CallerId: $callerId");
                    AsteriskAdapter::logdb(AsteriskAdapter::EVENTTYPE_DIAL, $number, $callerId);
                });

                $adapter->registerLinkListener(function(LinkEvent $event) use ($adapter){
                    $number = $event->getCallerID2();
                    $callerId = $event->getCallerID1();
                    $channel = $event->getChannel2();
                    $filename = $number . "-" . $callerId . "-" . date("Y-m-d-H-i-s");
                    $adapter->startChannelRecord($channel, $filename);
                    AsteriskAdapter::log("EVENT: Link Line: {$number} CallerId: $callerId");
                    AsteriskAdapter::logdb(AsteriskAdapter::EVENT_TYPE_LINK, $number, $callerId, $filename);
                });

                $adapter->registerBridgeListener(function(BridgeEvent $event) use ($adapter){
                    $number = $event->getCallerID2();
                    $callerId = $event->getCallerID1();
                    $channel = $event->getChannel2();
                    $filename = $number . "-" . $callerId . "-" . date("Y-m-d-H-i-s");
                    $adapter->startChannelRecord($channel, $filename);
                    AsteriskAdapter::log("EVENT: Bridge Line: {$number} CallerId: $callerId");
                    AsteriskAdapter::logdb(AsteriskAdapter::EVENT_TYPE_LINK, $number, $callerId, $filename);
                });

                $adapter->registerHangupListener(function(HangupEvent $event) use ($adapter){
                    $number = $adapter->getNumber($event->getChannel());
                    $callerId = null;
                    AsteriskAdapter::log("EVENT: Hangup Line: {$number} CallerId: $callerId");
                    AsteriskAdapter::logdb(AsteriskAdapter::EVENT_TYPE_HANGUP, $number, $callerId);
                });

                $adapter->registerNewAccountCodeListener("CLICKTODIAL", function(NewAccountCodeEvent $event) use ($adapter){
                    $channel = $event->getChannel();
                    $callerId = $adapter->getNumber($channel);
                    $filename = "CLICKTOCALL-" . $callerId . "-" . date("Y-m-d-H-i-s");
                    $adapter->startChannelRecord($channel, $filename);
                    AsteriskAdapter::log("EVENT: NewAccountCode CallerId: $callerId");
                    AsteriskAdapter::logdb(AsteriskAdapter::EVENT_TYPE_NEWACCOUNTCODE, "", $callerId, $filename);
                });

                while(true){
                    $adapter->client->process();
                }

            }catch (Exception $e){
                AsteriskAdapter::log("Exception: " . $e->getMessage());
            }

        }else{
            $errorMsg = $adapter->getConnectionError();
            AsteriskAdapter::log("ERROR: Can't connect to AMI {$errorMsg}");
            usleep(10000000);
        }
    }
}else{
    AsteriskAdapter::log("ERROR: Configuration vars not set");
    echo("ERROR: Configuration vars not set");
}

This script is running in command line and writes events to MySQL db.
When I start script on my Mac from terminal everything is good. It log all events to db.

missing event: Join

event: Join
privilege: call,all
channel: Local/5001@from-internal-61a6;2
calleridnum: 3216631398
calleridname: 3216631398
queue: 5001
position: 2
count: 2
uniqueid: 1301942099.1324731

PAMI Disconnect‏ and read Code

I am using PAMI to get Asterisk Manager Events. please see my code below. I wanted to get $event->getDialStatus() == 'ANSWER' of Dial Event and as condition true, i want Asterisk Manager to be disconnected and read the remaining code. in other words i just want to get some events store in DB and move to remaining after that. currently i am getting following error. Thanks.

'127.0.0.1', 'scheme' => 'tcp://', 'port' => 5038, 'username' => 'ncs', 'secret' => 'ncs', 'connect_timeout' => 10000, 'read_timeout' => 10000 ); $pamiClient = new PamiClient($pamiClientOptions); // Open the connection $pamiClient->open(); use PAMI\Message\Event\EventMessage; use PAMI\Message\Event\DialEvent; $pamiClient->registerEventListener(function (EventMessage $event) { print_r($event); }, function ($event) { $re = $event instanceof DialEvent && $event->getDialStatus() == 'ANSWER'; if ($re){ echo "Found Event\n"; global $pamiClient; $pamiClient->close(); } } ); $running = true; while($running) { $pamiClient->process(); usleep(1000); } echo "Code Ended>>>>>>>>>>>>>>>>>>> Read This Line\n"; ?>

PHP Fatal error: Uncaught exception 'PAMI\Client\Exception\ClientException' with message 'Error reading' in /usr/share/pear/PAMI/Client/Impl/ClientImpl.php:236
Stack trace:
#0 /usr/share/pear/PAMI/Client/Impl/ClientImpl.php(258): PAMI\Client\Impl\ClientImpl->getMessages()
#1 /scripts/pami.php(95): PAMI\Client\Impl\ClientImpl->process()
#2 {main}

thrown in /usr/share/pear/PAMI/Client/Impl/ClientImpl.php on line 236

add moduleload

ugly command. let's make 3 from this one: UnloadModuleAction, LoadModuleAction, ReloadActionModule

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.