2 namespace callnotifier;
5 * Watches EDSS1 messages for calls. Keeps an internal call state
6 * and notifies loggers of incoming and finished calls.
14 protected $currentCalls = array();
17 * Array of objects that are able to load details for a call
21 protected $detaillers = array();
23 public function __construct($config, $log)
25 $this->config = $config;
29 public function addDetailler(CallMonitor_Detailler $detailler)
31 $this->detaillers[] = $detailler;
34 public function handle(EDSS1_Message $msg)
36 $callId = $msg->callRef;
37 if (!array_key_exists($callId, $this->currentCalls)) {
38 $this->handleNew($callId, $msg);
40 $this->handleExisting($callId, $msg);
44 protected function handleNew($callId, EDSS1_Message $msg)
46 if ($msg->type != EDSS1_Message::SETUP) {
49 $this->currentCalls[$callId] = new CallMonitor_Call();
50 $this->handleSetup($callId, $msg);
54 protected function handleSetup($callId, EDSS1_Message $msg)
56 $call = $this->currentCalls[$callId];
57 $call->start = time();
58 if ($msg->tei == 127) {
59 $call->type = CallMonitor_Call::INCOMING;
61 $call->type = CallMonitor_Call::OUTGOING;
64 $this->handleParams($msg, $call, $callId);
68 protected function handleExisting($callId, EDSS1_Message $msg)
70 $call = $this->currentCalls[$callId];
73 case EDSS1_Message::INFORMATION:
74 $this->handleParams($msg, $call, $callId);
76 case EDSS1_Message::ALERTING:
77 if ($call->type == CallMonitor_Call::OUTGOING) {
79 * There may be two alerts: One from the telephone to the
80 * switchboard, and one from the switchboard to the target.
82 * The alert from the switchboard to the target call is
83 * sent first, so we can remove the call from the telephone
87 foreach ($this->currentCalls as $otherCallId => $otherCall) {
88 if ($otherCallId != $callId && $otherCall->to == $call->to) {
94 unset($this->currentCalls[$otherCallId]);
97 $this->loadCallDetails($call);
98 $this->log->log('startingCall', array('call' => $call));
101 case EDSS1_Message::RELEASE:
102 case EDSS1_Message::RELEASE_COMPLETE:
104 //we need to load details here because they might not have been
105 //loaded yet, e.g. for calls to MSNs that have no phones.
106 $this->loadCallDetails($call);
107 $this->log->log('finishedCall', array('call' => $call));
108 unset($this->currentCalls[$callId]);
113 protected function handleParams($msg, $call, $callId)
115 foreach ($msg->parameters as $param) {
116 switch ($param->type) {
117 case EDSS1_Parameter::CALLING_PARTY_NUMBER:
118 $call->from = $this->getFullNumber(
119 $param->number, $param->numberType
122 case EDSS1_Parameter::CALLED_PARTY_NUMBER:
123 $call->to = $this->getFullNumber(
124 $param->number, $param->numberType
126 if ($call->type == CallMonitor_Call::INCOMING
127 && $param->numberType != EDSS1_Parameter_Names::NUMBER_SUBSCRIBER
129 //only keep incoming calls that arrive at the switchboard,
130 // not the ones from the switchboard to the telephones
131 unset($this->currentCalls[$callId]);
134 case EDSS1_Parameter::KEYPAD:
135 if ($call->to === null) {
136 $call->to = $param->data;
143 protected function getFullNumber($number, $type)
145 if ($type == EDSS1_Parameter_Names::NUMBER_NATIONAL) {
146 return '0' . $number;
147 } else if ($type == EDSS1_Parameter_Names::NUMBER_INTERNATIONAL) {
148 return '+' . $number;
154 * Load details for a call, e.g. the name of the calling person
159 protected function loadCallDetails($call)
161 foreach ($this->detaillers as $detailler) {
162 $detailler->loadCallDetails($call);