1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
|
<?php
namespace callnotifier;
/**
* Watches EDSS1 messages for calls. Keeps an internal call state
* and notifies loggers of incoming and finished calls.
*
* Notifications:
* - startingCall
* - finishedCall
*/
class CallMonitor
{
protected $currentCalls = array();
public function __construct($config, $log)
{
$this->config = $config;
$this->log = $log;
}
public function handle(EDSS1_Message $msg)
{
$callId = $msg->callRef;
if (!array_key_exists($callId, $this->currentCalls)) {
$this->handleNew($callId, $msg);
} else {
$this->handleExisting($callId, $msg);
}
}
protected function handleNew($callId, EDSS1_Message $msg)
{
if ($msg->type != EDSS1_Message::SETUP) {
return;
}
$this->currentCalls[$callId] = new CallMonitor_Call();
$this->handleSetup($callId, $msg);
}
protected function handleSetup($callId, EDSS1_Message $msg)
{
$call = $this->currentCalls[$callId];
$call->start = time();
if ($msg->tei == 127) {
$call->type = CallMonitor_Call::INCOMING;
} else {
$call->type = CallMonitor_Call::OUTGOING;
}
$this->handleParams($msg, $call, $callId);
}
protected function handleExisting($callId, EDSS1_Message $msg)
{
$call = $this->currentCalls[$callId];
switch ($msg->type) {
case EDSS1_Message::INFORMATION:
$this->handleParams($msg, $call, $callId);
break;
case EDSS1_Message::ALERTING:
if ($call->type == CallMonitor_Call::OUTGOING) {
/**
* There may be two alerts: One from the telephone to the
* switchboard, and one from the switchboard to the target.
*
* The alert from the switchboard to the target call is
* sent first, so we can remove the call from the telephone
* to the switchboard.
*/
$bFound = false;
foreach ($this->currentCalls as $otherCallId => $otherCall) {
if ($otherCallId != $callId && $otherCall->to == $call->to) {
$bFound = true;
break;
}
}
if ($bFound) {
unset($this->currentCalls[$otherCallId]);
}
}
$this->log->log('startingCall', array('call' => $call));
break;
case EDSS1_Message::RELEASE:
case EDSS1_Message::RELEASE_COMPLETE:
$call->end = time();
$this->log->log('finishedCall', array('call' => $call));
unset($this->currentCalls[$callId]);
break;
}
}
protected function handleParams($msg, $call, $callId)
{
foreach ($msg->parameters as $param) {
switch ($param->type) {
case EDSS1_Parameter::CALLING_PARTY_NUMBER:
$call->from = $this->getFullNumber(
$param->number, $param->numberType
);
break;
case EDSS1_Parameter::CALLED_PARTY_NUMBER:
$call->to = $this->getFullNumber(
$param->number, $param->numberType
);
if ($call->type == CallMonitor_Call::INCOMING
&& $param->numberType != EDSS1_Parameter_Names::NUMBER_SUBSCRIBER
) {
//only keep incoming calls that arrive at the switchboard,
// not the ones from the switchboard to the telephones
unset($this->currentCalls[$callId]);
}
break;
case EDSS1_Parameter::KEYPAD:
if ($call->to === null) {
$call->to = $param->data;
}
}
}
}
protected function getFullNumber($number, $type)
{
if ($type == EDSS1_Parameter_Names::NUMBER_NATIONAL) {
return '0' . $number;
}
return $number;
}
}
?>
|