read TEI and call reference
[auerswald-callnotifier.git] / src / callnotifier / MessageHandler.php
1 <?php
2 namespace callnotifier;
3
4 class MessageHandler
5 {
6     protected $dumpHdl;
7
8     /**
9      * Array of logger object arrays.
10      * Key is the notification type, value is an array of logger objects
11      * that want to get notified about the type.
12      *
13      * @var array
14      */
15     protected $logger = array(
16         'msgData' => array(),
17         'incomingCall' => array(),
18         'edss1msg' => array(),
19     );
20
21
22     public function __construct($config)
23     {
24         $this->config = $config;
25         $this->prepareDump();
26     }
27
28     /**
29      * Add a logger
30      *
31      * @param Logger       $logger Logger object to register
32      * @param array|string $types  Single notification type or array of such
33      *                             types. "*" means "register for all types".
34      *
35      * @return self
36      */
37     public function addLogger(Logger $logger, $types)
38     {
39         if ($types == '*') {
40             $types = array_keys($this->logger);
41         }
42         $types = (array)$types;
43
44         foreach ($types as $type) {
45             if (!isset($this->logger[$type])) {
46                 throw new \Exception('Unknown log type: ' . $type);
47             }
48             $this->logger[$type][] = $logger;
49         }
50     }
51
52     public function handle($msg)
53     {
54         if ($this->config->dumpFile !== null) {
55             $this->dump($msg);
56         }
57         if (substr($msg, 0, 9) != '[DKANPROT') {
58             //unknown message type
59             return;
60         }
61         $regex = '#^\\[DKANPROT-([^ ]+) ([0-9]+)\\] (.*)$#';
62         if (!preg_match($regex, $msg, $matches)) {
63             //message should always be that way
64             return false;
65         }
66         list(, $type, $someid, $details) = $matches;
67         $this->log(
68             'msgData',
69             array(
70                 'type' => $type,
71                 'id' => $someid,
72                 'details' => $details
73             )
74         );
75
76         if ($type != 'Info') {
77             $this->parseEDSS1($details);
78             return;
79         }
80         //Vegw/Ets-Cref:[0xffef]/[0x64] - VEGW_SETUP from upper layer to internal destination: CGPN[**22]->CDPN[41], 
81         $regex = '#CGPN\\[([^\\]]+)\\]->CDPN\\[([^\\]]+)\\]#';
82         if (preg_match($regex, $details, $matches)) {
83             list(, $from, $to) = $matches;
84             $this->log('incomingCall', array('from' => $from, 'to' => $to));
85         }
86     }
87
88     /**
89      * Example string: "T02: 00 A3 06 0A 08 01 01 5A FF 0A"
90      *
91      * @param string $details Detail string of a debug message
92      *
93      */
94     protected function parseEDSS1($details)
95     {
96         if ($details{0} != 'T' && $details{0} != 'N') {
97             //we only want byte data
98             return;
99         }
100         if (substr($details, 16, 4) != ' 08 ') {
101             //only E-DSS-1, no other packets
102             return;
103         }
104         
105         $bytestring = substr($details, 5);
106         $bytes = static::getBytesFromHexString($bytestring);
107
108         $msgtype = $bytes{7};
109         static $interestingTyps = array(
110             EDSS1_Message::SETUP,
111             EDSS1_Message::CONNECT,
112             EDSS1_Message::INFORMATION
113         );
114         if (!in_array($msgtype, $interestingTyps)) {
115             //return;
116         }
117
118         $mp = new EDSS1_Parser();
119         $msg = $mp->parse($bytes);
120
121         $this->log('edss1msg', array('msg' => $msg));
122     }
123
124     protected function log($type, $arData)
125     {
126         if (!isset($this->logger[$type])) {
127             throw new \Exception('Unknown log type: ' . $type);
128         }
129         
130         if (count($this->logger[$type])) {
131             foreach ($this->logger[$type] as $logger) {
132                 $logger->log($type, $arData);
133             }
134         }
135     }
136
137     public static function getBytesFromHexString($bytestring)
138     {
139         $bytes = '';
140         foreach (explode(' ', $bytestring) as $strbyte) {
141             $bytes .= chr(hexdec($strbyte));
142         }
143         return $bytes;
144     }
145
146     protected function prepareDump()
147     {
148         if ($this->config->dumpFile === null) {
149             return;
150         }
151         $this->dumpHdl = fopen($this->config->dumpFile, 'w');
152         if (!$this->dumpHdl) {
153             throw new Exception('Cannot open replay file for reading');
154         }
155     }
156
157     protected function dump($msg)
158     {
159         fwrite($this->dumpHdl, $msg . "\n");
160     }
161 }
162
163 ?>