* and notifies loggers of incoming and finished calls.
*
* Notifications:
- * - incomingCall
+ * - startingCall
* - finishedCall
*/
class CallMonitor
{
protected $currentCalls = array();
+ /**
+ * Array of objects that are able to load details for a call
+ *
+ * @var array
+ */
+ protected $detaillers = array();
+
public function __construct($config, $log)
{
$this->config = $config;
$this->log = $log;
}
+ public function addDetailler(CallMonitor_Detailler $detailler)
+ {
+ $this->detaillers[] = $detailler;
+ }
+
public function handle(EDSS1_Message $msg)
{
$callId = $msg->callRef;
{
$call = $this->currentCalls[$callId];
$call->start = time();
- $this->handleParams($call, $msg);
+ if ($msg->tei == 127) {
+ $call->type = CallMonitor_Call::INCOMING;
+ } else {
+ $call->type = CallMonitor_Call::OUTGOING;
+ }
+
+ $this->handleParams($msg, $call, $callId);
}
switch ($msg->type) {
case EDSS1_Message::INFORMATION:
- $this->handleParams($call, $msg);
+ $this->handleParams($msg, $call, $callId);
break;
- case EDSS1_Message::CALL_PROCEEDING:
- $this->log->log('incomingCall', array('call' => $call));
+ 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->loadCallDetails($call);
+ $this->log->log('startingCall', array('call' => $call));
break;
case EDSS1_Message::RELEASE:
case EDSS1_Message::RELEASE_COMPLETE:
$call->end = time();
+ //we need to load details here because they might not have been
+ //loaded yet, e.g. for calls to MSNs that have no phones.
+ $this->loadCallDetails($call);
$this->log->log('finishedCall', array('call' => $call));
unset($this->currentCalls[$callId]);
break;
}
}
- protected function handleParams($call, $msg)
+ protected function handleParams($msg, $call, $callId)
{
foreach ($msg->parameters as $param) {
switch ($param->type) {
case EDSS1_Parameter::CALLING_PARTY_NUMBER:
- $call->from = $param->number;
+ $call->from = $this->getFullNumber(
+ $param->number, $param->numberType
+ );
break;
case EDSS1_Parameter::CALLED_PARTY_NUMBER:
- $call->to = $param->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;
+ } else if ($type == EDSS1_Parameter_Names::NUMBER_INTERNATIONAL) {
+ return '+' . $number;
+ }
+ return $number;
+ }
+
+ /**
+ * Load details for a call, e.g. the name of the calling person
+ * or the area
+ *
+ * @return void
+ */
+ protected function loadCallDetails($call)
+ {
+ foreach ($this->detaillers as $detailler) {
+ $detailler->loadCallDetails($call);
+ }
+ }
}
?>