marcelog/PAMI — pull request #31 by jacobkiers (2012-07-12 13:11:31+00:00)
Title: Allow setting the ActionID on an Action message.

Hi Marcelo,

I have added the possibility to override the ActionID, including tests. The default behaviour (automatically generating it with microtime), has not changed.

I would appriciate it if you pulled these changes.

**Rationale**
Only the thread sending the Originate knows the ActionID it was sent with. Since the default behaviour is using microtime(true), this means that only that thread can matche the OriginateResponseEvent to the corresponding call. By adding the ability to set the ActionID, another process can handle AMI messages, and still know to which call an OriginateResponseEvent belongs.

This gives the possibility to separate call setup with response handling.

**Example**
Let's say we have 2 processes: the first is a Dialer, a very dumb process, just sending OriginateActions. The other one is a Reporter, handling all aspects of reporting calls, like custom handling of HangupEvent and OriginateResponseEvent messages.

The Dialer (process 1) sends an OriginateMessage:
```php
setActionID('AFBCE1436'); // The newly added function
$originate->setVariable('unique-job-id', 'AFBCE1436');
$originate->setTimeout(30000); // 30 seconds
// and so on

$pami->send($originate);
```

```
Action: Originate
Channel: SIP/101@outbound
Context: default
Exten: 8135551212
Priority: 1
Callerid: 3125551212
Timeout: 30000
Variable: unique-job-id=AFBCE1436
ActionID: AFBCE1436
```

Now, calling user 101@outbound fails with a timout on the Originate, giving the following two events. As you can see, the HangupEvent just says that everything is OK (Cause 16 - Normal call clearing), while the OriginateReponseEvent knows that this call timed out (Reason 3).

As you also can see, the only thing in common is now the unique job id on the channel and the same one in the Action ID.

```
Event: Hangup
Privilege: call,all
Timestamp: 1341587531.893844
Channel: SIP/outbound-00000018
Uniqueid: 1341587529.24
CallerIDNum: 101
CallerIDName:
Cause: 16
Cause-txt: Normal Clearing

Event: OriginateResponse
Privilege: call,all
Timestamp: 1341828502.526406
ActionID: AFBCE1436
Response: Failure
Channel: SIP/101@outbound
Context: voiceapi
Exten:
Reason: 3
Uniqueid:
CallerIDNum:
CallerIDName:
```
Example code to show how to match them:

```php
getChannel(), 'unique-job-id');
$var = $pami->send($getVar);
$hangup_uid = $var->getKey('unique-job-id');

/* @var $originate OriginateResponseEvent*/
$originate_uid = $originate->getActionID();

if ($hangup_iud == $originate_uid) {
if ($hangup->getCause() == 16 && $originate->getReason() == 3) {
echo "Call {$hangup_uid} timed out!" . PHP_EOL;
}
}
```

As you can see, because of the ActionID we can match the OriginateResponseEvent to the HangupEvent, because, during a failure, the OriginateResponseEvent returns the *originally called number* as the Channel.

**Original situation**
In the original situation, the following events would be generated. As you can see, there's no way to match them:

```
Event: Hangup
Privilege: call,all
Timestamp: 1341587531.893844
Channel: SIP/outbound-00000018
Uniqueid: 1341587529.24
CallerIDNum: 101
CallerIDName:
Cause: 16
Cause-txt: Normal Clearing

Event: OriginateResponse
Privilege: call,all
Timestamp: 1341828502.526406
ActionID: 1341828499.5255
Response: Failure
Channel: SIP/101@outbound
Context: voiceapi
Exten:
Reason: 3
Uniqueid:
CallerIDNum:
CallerIDName:
```