File Coverage

blib/lib/Net/CSTAv3/Client.pm
Criterion Covered Total %
statement 13 304 4.2
branch 0 30 0.0
condition 0 30 0.0
subroutine 5 44 11.3
pod 7 35 20.0
total 25 443 5.6


line stmt bran cond sub pod time code
1             package Net::CSTAv3::Client;
2              
3 1     1   24666 use Carp;
  1         3  
  1         148  
4 1     1   5 use strict;
  1         1  
  1         35  
5 1     1   5 use warnings;
  1         5  
  1         27  
6 1     1   1012 use Convert::ASN1::asn1c;
  1         68181  
  1         72  
7              
8             require Exporter;
9              
10             BEGIN {
11 1     1   1494 require Net::CSTAv3::Client::HiPath;
12             }
13              
14             our @ISA = qw(Exporter);
15              
16             # Items to export into callers namespace by default. Note: do not export
17             # names by default without a very good reason. Use EXPORT_OK instead.
18             # Do not simply export all your public functions/methods/constants.
19              
20             # This allows declaration use Net::CSTAv3::Client ':all';
21             # If you do not need this, moving things directly into @EXPORT or @EXPORT_OK
22             # will save memory.
23             our %EXPORT_TAGS = ( 'all' => [ qw(
24            
25             ) ] );
26              
27             our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } );
28              
29             our @EXPORT = qw(
30            
31             );
32              
33             our $VERSION = '0.06';
34              
35             sub debug {
36 0     0 0   my $self = shift;
37 0 0         if ($self->{'_debug_state'}) {
38 0           print( "[DEBUG] " . join('', @_));
39             }
40             }
41              
42             sub decode_msg_header {
43 0     0 0   my $self = shift;
44 0           my $bin = shift;
45 0           my ($header, $b1, $b2) = unpack('CCC', $bin);
46 0 0         croak "Not a valid Siemens Hipath data packet\n" unless ($header == 0x26);
47 0           $b1 -= 128; # "MSB" of len field is always 1
48 0           my $len = ($b1 << 8) + $b2;
49 0           return $len;
50             }
51              
52             sub encode_msg_header {
53 0     0 0   my $self = shift;
54 0           my $len = shift;
55 0 0         die "Message larger than allowed!" unless ($len <= 1000);
56 0           my $bin = pack('Cn', 38, $len+(1<<15));
57 0           return $bin;
58             }
59              
60             sub open_csta_socket {
61 0     0 0   my $self = shift;
62 0           my $host = shift;
63 0           my $port = shift;
64              
65 0           $self->debug("trying to open a connection to $host on port $port\n");
66            
67 0   0       my $socket = new IO::Socket::INET(
68             PeerAddr => $host,
69             PeerPort => $port,
70             Blocking => 1,
71             Proto => 'tcp') || die "Error creating socket: $!\n";
72 0           $socket->autoflush(1);
73 0           $self->debug("opened a connection to $host on port $port\n");
74 0           $self->{'_csta_socket'} = $socket;
75             }
76              
77             sub send_pdu {
78 0     0 0   my $self = $_[0];
79 0           my $pdu = $_[1];
80 0           my $header = $self->encode_msg_header(length($pdu));
81 0           $self->{'_csta_socket'}->write($header);
82 0           my $hexdata = $self->convert_to_hex($header);
83 0           $self->{'_csta_socket'}->write($pdu);
84 0           $hexdata = $self->convert_to_hex($pdu);
85 0           $self->debug("SENT PDU: [$hexdata]\n");
86             }
87              
88             sub send_aarq {
89 0     0 0   my $self = $_[0];
90 0           my %args = %{$_[1]};
  0            
91 0           my $conv = Convert::ASN1::asn1c->new();
92 0           my $pdu = $conv->sencode(Net::CSTAv3::Client::HiPath::AARQ_apdu(), {
93             'sender-acse-requirements'=>$conv->encode_bitstring('10'),
94             'authentication-name'=>$conv->encode_octet_string($args{authname}),
95             'authentication-password'=>$conv->encode_octet_string($args{password}),
96             'csta-version'=>$conv->encode_bitstring('0001000000000000'),
97             'authentication-password_length'=>length($args{password}),
98             'authentication-name_length'=>length($args{authname})
99             });
100 0 0         croak "Couldn't encode AARQ-apdu!\n" unless (defined $pdu);
101 0           $self->debug("SENDING AARQ-apdu\n");
102 0           $self->send_pdu($pdu);
103             }
104              
105             sub receive_aare {
106 0     0 0   my $self = $_[0];
107 0           my $pdu = $self->receive_stuff();
108 0           my $conv = Convert::ASN1::asn1c->new();
109 0           my $values = $conv->sdecode(Net::CSTAv3::Client::HiPath::AARE_apdu(), $pdu);
110 0           $self->debug("RECEIVED AARE-apdu\n");
111 0           $self->debug("> result: $values->{'result'} (0=accepted, 1=rejected permanent, 2=rejected transient)\n");
112 0           $self->debug("> aps-stamp: $values->{'aps-stamp'}\n");
113 0           $self->debug("> system-version: $values->{'system-version'}\n");
114 0           return $values;
115             }
116              
117             sub send_abrt {
118 0     0 0   my $self = $_[0];
119 0           my $conv = Convert::ASN1::asn1c->new();
120 0           my $pdu = $conv->sencode(Net::CSTAv3::Client::HiPath::ABRT_apdu(), { });
121 0 0         croak "Couldn't encode ABRT-apdu!\n" unless (defined $pdu);
122 0           $self->debug("SENDING ABRT-apdu\n");
123 0           $self->send_pdu($pdu);
124             }
125              
126             sub receive_csta_system_status {
127 0     0 0   my $self = $_[0];
128 0           my $pdu = $self->receive_stuff();
129 0           my $conv = Convert::ASN1::asn1c->new();
130 0           my $values = $conv->sdecode(Net::CSTAv3::Client::HiPath::CSTA_SystemStatus(), $pdu);
131 0           $self->debug("RECEIVED CSTA-SystemStatus\n");
132             # system-status is an enumerated integer, we have to decode it ourselves
133 0           $values->{'system-status'} = $conv->decode_integer($values->{'system-status'}, $values->{'system-status_length'});
134 0           $self->debug("> invoke-id: $values->{'invoke-id'}\n");
135 0           $self->debug("> operation-value: $values->{'operation-value'}\n");
136 0           $self->debug("> system-status: $values->{'system-status'}\n");
137 0           return $values;
138             }
139              
140             sub send_csta_system_status_response {
141 0     0 0   my $self = $_[0];
142 0           my %args = %{$_[1]};
  0            
143 0           my $conv = Convert::ASN1::asn1c->new();
144 0           my $pdu = $conv->sencode(Net::CSTAv3::Client::HiPath::CSTA_SystemStatusResponse(),
145             {'invoke-id'=>$conv->encode_integer($args{'invoke-id'}, $args{'invoke-id_length'}),
146             'operation-value'=>$conv->encode_integer($args{'operation-value'}, $args{'operation-value_length'})
147             });
148 0           $self->debug("SENDING CSTA-SystemStatusResponse\n");
149 0           $self->send_pdu($pdu);
150             }
151              
152             sub send_csta_monitor_start {
153              
154 0     0 0   my $self = $_[0];
155 0           my %args = %{$_[1]};
  0            
156              
157             # NOTE: It seems that our PBX, contrary to the SwitchSimulator, only monitors ALL events if all bits are set to 0.
158              
159             # call-control: 18 bits, meaning: bit 0 ....... 17
160             # unknown, conferenced, connectionCleared, delivered, diverted, established,
161             # failed, held, networkReached, originated, queued, retrieved, serviceInitiated, transferred, 4 x unknown
162             # call-associated: 5 bits, meaning: bit 0 ...... 4
163             # unknown, charging, 3 x unknown
164             # media-attachment: 2 bits, meaning 2 xunknown
165             # physical-device-feature: 11 bits, meaning: bit 0 ..... 10
166             # buttonInformation, buttonPress, unknown, hookswitch, unknown, messageWaiting, 5 x unknown
167             # logical-device-feature: 14 bits, meaning: bit 0 ...... 14
168             # agentBusy, agentLoggedOn, agentLoggedOff, agentNotReady, agentReady, agentWorkingAfterCall,
169             # 5 x unknown, doNotDisturb, forwarding, unknown
170             # maintainance: 3 bits, meaning: bit 0 ...... 2
171             # backInService, outOfService, unknown
172             # voice-unit: 7 bits, meaning: bit 0 ...... 6
173             # play, stop, 5 x unknown
174             # private: 1 bit meaning unknown
175              
176             # ALL UNKNOWN BITS SHOULD ALWAYS BE ZERO!
177            
178 0           my $conv = Convert::ASN1::asn1c->new();
179            
180 0   0       my $pdu = $conv->sencode(Net::CSTAv3::Client::HiPath::CSTA_MonitorStart(), {
      0        
      0        
      0        
      0        
      0        
      0        
      0        
181             'invoke-id'=>$conv->encode_integer($args{'invoke-id'}, 1),
182             'invoke-id_length'=>1, #TODO handle length correctly
183             'operation-value'=>$conv->encode_integer(71, 1),
184             'operation-value_length'=>1,
185             'dialing-number'=>$conv->encode_octet_string($args{'dialing-number'}),
186             'dialing-number_length'=>length($args{'dialing-number'}),
187             'call-control'=>$conv->encode_bitstring($args{'call-control'} || '000000000000000000'),
188             'call-associated'=>$conv->encode_bitstring($args{'call-associated'} || '00000'),
189             'media-attachment'=>$conv->encode_bitstring($args{'media-attachment'} || '00'),
190             'physical-device-feature'=>$conv->encode_bitstring($args{'physical-device-feature'} || '00000000000'),
191             'logical-device-feature'=>$conv->encode_bitstring($args{'logical-device-feature'} || '00000000000000'),
192             'maintainance'=>$conv->encode_bitstring($args{'maintainance'} || '000'),
193             'voice-unit'=>$conv->encode_bitstring($args{'voice-unit'} || '0000000'),
194             'private'=>$conv->encode_bitstring($args{'private'} || '0'),
195             });
196 0           $self->debug("SENDING CSTA-MonitorStart\n");
197 0           $self->send_pdu($pdu);
198            
199             }
200              
201             sub receive_csta_monitor_start_response {
202 0     0 0   my $self = $_[0];
203 0           my $conv = Convert::ASN1::asn1c->new();
204 0           my $pdu = $self->receive_stuff();
205 0           my $values = $conv->sdecode(Net::CSTAv3::Client::HiPath::CSTA_MonitorStartResponse(), $pdu);
206             # cross-ref-identifier is actually an octet string but we can not print it as such as it may contain null bytes at the beginning
207             # so we will just treat it as a binary object (it is an opaque object anyway)
208 0           $values->{'cross-ref-identifier'} = $conv->decode_xml2hextxt($values->{'cross-ref-identifier_orig'});
209 0           $self->debug("RECEIVED CSTA-MonitorStartResponse\n");
210 0           $self->debug("< cross-ref-identifier: $values->{'cross-ref-identifier'}\n");
211 0           return $values;
212             }
213              
214             sub send_csta_monitor_stop {
215              
216 0     0 0   my $self = $_[0];
217 0           my %args = %{$_[1]};
  0            
218              
219 0           my $conv = Convert::ASN1::asn1c->new();
220              
221 0           my $pdu = $conv->sencode(Net::CSTAv3::Client::HiPath::CSTA_MonitorStop(), {
222             'cross-ref-identifier'=>$conv->encode_hextxt2xml($args{'cross-ref-identifier'}, 1),
223             'cross-ref-identifier_length'=>length($args{'cross-ref-identifier'})/2,
224             'invoke-id'=>$conv->encode_integer($args{'invoke-id'}, 1),
225             'invoke-id_length'=>1, #TODO handle length correctly
226             });
227 0           $self->debug("SENDING CSTA-MonitorStop\n");
228 0           $self->send_pdu($pdu);
229            
230             }
231              
232             sub receive_csta_monitor_stop_response {
233 0     0 0   my $self = $_[0];
234 0           my $conv = Convert::ASN1::asn1c->new();
235 0           my $pdu = $self->receive_stuff();
236 0           my $values = $conv->sdecode(Net::CSTAv3::Client::HiPath::CSTA_MonitorStopResponse(), $pdu);
237 0           $self->debug("RECEIVED CSTA-MonitorStopResponse\n");
238 0           return $values;
239             }
240              
241              
242              
243             sub convert_to_hex {
244 0     0 0   my $self = $_[0];
245 0           my $pdu = $_[1];
246 0           my $hexdata = unpack('H*', $pdu);
247 0           $hexdata =~ tr/a-z/A-Z/;
248 0           $hexdata =~ s/(..)/$1 /g;
249 0           $hexdata =~ s/ $//g;
250 0           return $hexdata;
251             }
252              
253              
254             sub receive_stuff {
255 0     0 0   my $self = $_[0];
256 0           my $header = '';
257 0           my $pdu = '';
258 0           my $nbytes = $self->{'_csta_socket'}->sysread($header, 3);
259 0 0         croak "Didn't receive the specified amount of data!\n" unless ($nbytes == 3);
260 0           $self->debug("Received three bytes, assuming it's a message header\n");
261 0           my $len = $self->decode_msg_header($header);
262 0           $self->debug("Waiting for $len bytes of ASN1 data now\n");
263 0           $nbytes = $self->{'_csta_socket'}->sysread($pdu, $len);
264             # TODO sysread can return with fewer bytes, has to be called in a loop
265 0 0         croak "Didn't receive the specified amount of data!\n" unless ($nbytes == $len);
266 0           my $hexdata = $self->convert_to_hex($pdu);
267 0           $self->debug("RECEIVED PDU: [$hexdata]\n");
268 0           return $pdu;
269             }
270              
271             sub csta_connect {
272 0     0 1   my $self = $_[0];
273 0           my %args = %{$_[1]};
  0            
274 0           $self->open_csta_socket($args{host}, $args{port});
275 0   0       $self->send_aarq({authname=>$args{authname}||"AMHOST", password=>$args{password}||'77777'});
      0        
276 0           $self->receive_aare();
277 0           my $ret = $self->receive_csta_system_status();
278 0           $self->send_csta_system_status_response($ret);
279             }
280              
281             sub csta_disconnect {
282 0     0 0   my $self = $_[0];
283 0           $self->send_abrt();
284 0           close($self->{'_csta_socket'});
285             }
286              
287             sub csta_setup_monitoring {
288 0     0 1   my $self = $_[0];
289 0           my %args = %{$_[1]};
  0            
290            
291 0           $self->send_csta_monitor_start({'invoke-id'=>1, 'dialing-number'=>$args{'dialing-number'}});
292 0           my $ret = $self->receive_csta_monitor_start_response();
293              
294 0 0         if (defined $ret->{'cross-ref-identifier'}) {
295             $self->{'_active_monitorings'}->{$ret->{'cross-ref-identifier'}} = {
296             'dialing_number' => $args{'dialing-number'},
297 0     0     'delivered_cb' => $args{'delivered_cb'} || sub {},
298 0     0     'cleared_cb' => $args{'cleared_cb'} || sub{},
299 0     0     'established_cb' => $args{'established_cb'} || sub{},
300 0     0     'transferred_cb' => $args{'transferred_cb'} || sub{},
301             }
302 0   0       }
      0        
      0        
      0        
303              
304 0           return $ret->{'cross-ref-identifier'};
305             }
306              
307             sub csta_destroy_monitoring {
308 0     0 1   my $self = $_[0];
309 0           my %args = %{$_[1]};
  0            
310 0           $self->send_csta_monitor_stop({'cross-ref-identifier'=>$args{'cross-ref-identifier'}, 'invoke-id'=>2});
311 0           $self->receive_csta_monitor_stop_response();
312             }
313              
314             sub parse_any_csta_packet {
315              
316             # not really true! we are expecting an event report here!
317              
318 0     0 0   my ($self, $pdu) = @_;
319 0           my $conv = Convert::ASN1::asn1c->new();
320 0           my $values = $conv->sdecode(Net::CSTAv3::Client::HiPath::CSTA_RosePacketDecode(), $pdu);
321 0 0         if ($values->{'operation-value'} == 21) {
322 0           $self->parse_csta_event_report($pdu);
323             }
324             else {
325 0           $self->debug("I received an unexpected packet!\n");
326             }
327             }
328              
329             sub parse_csta_event_report {
330 0     0 0   my ($self, $pdu) = @_;
331 0           my $pdu_copy = $pdu;
332              
333             # get the first three tags in the tree of the packet to find out what kind of
334             # event report we are dealing with - their meaning is:
335             # [1] -- always the same
336             # [UNIVERSAL 16] -- always the same
337             # [0] -- CallControlServAndEvents (all other packets are uninteresting)
338             # [3] -- event type
339             # interesting types are
340             # connectionCleared [ 3]
341             # delivered [ 4]
342             # established [ 7]
343             # originated [13]
344             # transferred [17]
345              
346 0           my $conv = Convert::ASN1::asn1c->new();
347 0           my $tagpaths = $conv->get_tagpaths_with_prefix($pdu, "[1]|[UNIVERSAL 16]|[0]|");
348 0           my $node = $tagpaths->[0];
349 0           my $packettype = undef;
350 0           my $escaped_regex = quotemeta("[1]|[UNIVERSAL 16]|[0]|");
351 0 0         if ($node =~ /$escaped_regex \[(\d+)\]/x) {
352 0           $packettype = $1;
353             }
354              
355 0 0         if (defined $packettype) {
356 0 0         if ($packettype == 3) {
    0          
    0          
    0          
357 0           $self->parse_connection_cleared_event($pdu_copy);
358             }
359             elsif ($packettype == 4) {
360 0           $self->parse_delivered_event($pdu_copy);
361             }
362             elsif ($packettype == 7) {
363 0           $self->parse_established_event($pdu_copy);
364             }
365             elsif ($packettype == 17) {
366 0           $self->parse_transferred_event($pdu_copy);
367             }
368             else {
369 0           $self->debug("I am ignoring this Event because the handling of this eventtype is not implemented\n");
370             }
371             # parse_diverted_event($pdu) if ($packettype == 6);
372             # parse_originated_event($pdu) if ($packettype == 13);
373             }
374             else {
375 0           $self->debug("I am ignoring this Event because it is not a call-event\n");
376             }
377              
378             }
379              
380             sub parse_connection_cleared_event {
381 0     0 0   my ($self, $pdu) = @_;
382            
383 0           my $conv = Convert::ASN1::asn1c->new();
384              
385 0           my $values = $conv->sdecode(Net::CSTAv3::Client::HiPath::CSTA_EventReport_ConnectionCleared(), $pdu);
386 0           $values->{'dialing-number'} = $conv->decode_octet_string($values->{'dialing-number_orig'}, $values->{'dialing-number_length'});
387 0           $values->{'cross-ref-identifier'} = $conv->decode_xml2hextxt($values->{'cross-ref-identifier_orig'});
388 0           $values->{'connection-info'} = $conv->decode_integer($values->{'connection-info_orig'}, $values->{'connection-info_length'});
389 0           $values->{'releasing-device'} = $conv->decode_octet_string($values->{'releasing-device_orig'}, $values->{'releasing-device_length'});
390 0           $values->{'call-id'} = $conv->decode_xml2hextxt($values->{'call-id_orig'});
391              
392 0           $self->debug("EVENT RECEIVED: connection cleared event:\n");
393 0           $self->debug("> cross-ref-identifier: $values->{'cross-ref-identifier'}\n");
394 0           $self->debug("> call-id: $values->{'call-id'}\n");
395 0           $self->debug("> dialing-number: $values->{'dialing-number'}\n");
396 0           $self->debug("> releasing-device: $values->{'releasing-device'}\n");
397 0           $self->debug("> timestamp: $values->{'timestamp'}\n");
398              
399 0           $self->{'_active_monitorings'}->{$values->{'cross-ref-identifier'}}->{'cleared_cb'}->($values);
400              
401 0           return $values;
402             }
403              
404             sub parse_established_event {
405 0     0 0   my ($self, $pdu) = @_;
406 0           my $conv = Convert::ASN1::asn1c->new();
407 0           my $values = $conv->sdecode(Net::CSTAv3::Client::HiPath::CSTA_EventReport_Established(), $pdu);
408 0           $values->{'dialing-number'} = $conv->decode_octet_string($values->{'dialing-number_orig'}, $values->{'dialing-number_length'});
409 0           $values->{'answering-device'} = $conv->decode_octet_string($values->{'answering-device_orig'}, $values->{'answering-device_length'});
410 0           $values->{'calling-device'} = $conv->decode_octet_string($values->{'calling-device_orig'}, $values->{'calling-device_length'});
411 0           $values->{'called-device'} = $conv->decode_octet_string($values->{'called-device_orig'}, $values->{'called-device_length'});
412 0           $values->{'cross-ref-identifier'} = $conv->decode_xml2hextxt($values->{'cross-ref-identifier_orig'});
413 0           $values->{'connection-info'} = $conv->decode_integer($values->{'connection-info_orig'}, $values->{'connection-info_length'});
414 0           $values->{'call-id'} = $conv->decode_xml2hextxt($values->{'call-id_orig'});
415              
416 0           $self->debug("EVENT RECEIVED: established event:\n");
417 0           $self->debug("> cross-ref-identifier: $values->{'cross-ref-identifier'}\n");
418 0           $self->debug("> call-id: $values->{'call-id'}\n");
419 0           $self->debug("> answering-device: $values->{'answering-device'}\n");
420 0           $self->debug("> calling-device: $values->{'calling-device'}\n");
421 0           $self->debug("> called-device: $values->{'called-device'}\n");
422 0           $self->debug("> timestamp: $values->{'timestamp'}\n");
423              
424 0           $self->{'_active_monitorings'}->{$values->{'cross-ref-identifier'}}->{'established_cb'}->($values);
425            
426 0           return $values;
427             }
428              
429             sub parse_delivered_event {
430 0     0 0   my ($self, $pdu) = @_;
431              
432 0           my $conv = Convert::ASN1::asn1c->new();
433              
434 0           my $values = $conv->sdecode(Net::CSTAv3::Client::HiPath::CSTA_EventReport_Delivered(), $pdu);
435 0           $values->{'dialing-number'} = $conv->decode_octet_string($values->{'dialing-number_orig'}, $values->{'dialing-number_length'});
436 0           $values->{'alerting-device'} = $conv->decode_octet_string($values->{'alerting-device_orig'}, $values->{'alerting-device_length'});
437 0           $values->{'calling-device'} = $conv->decode_octet_string($values->{'calling-device_orig'}, $values->{'calling-device_length'});
438 0           $values->{'called-device'} = $conv->decode_octet_string($values->{'called-device_orig'}, $values->{'called-device_length'});
439 0           $values->{'cross-ref-identifier'} = $conv->decode_xml2hextxt($values->{'cross-ref-identifier_orig'});
440 0           $values->{'call-id'} = $conv->decode_xml2hextxt($values->{'call-id_orig'});
441 0           $values->{'connection-info'} = $conv->decode_integer($values->{'connection-info_orig'}, $values->{'connection-info_length'});
442              
443 0           $self->debug("EVENT RECEIVED: delivered event:\n");
444 0           $self->debug("> cross-ref-identifier: $values->{'cross-ref-identifier'}\n");
445 0           $self->debug("> call-id: $values->{'call-id'}\n");
446 0           $self->debug("> alerting-device: $values->{'alerting-device'}\n");
447 0           $self->debug("> calling-device: $values->{'calling-device'}\n");
448 0           $self->debug("> called-device: $values->{'called-device'}\n");
449 0           $self->debug("> timestamp: $values->{'timestamp'}\n");
450              
451 0           $self->{'_active_monitorings'}->{$values->{'cross-ref-identifier'}}->{'delivered_cb'}->($values);
452            
453 0           return $values;
454             }
455              
456             sub parse_transferred_event {
457 0     0 0   my ($self, $pdu) = @_;
458              
459 0           my $conv = Convert::ASN1::asn1c->new();
460              
461 0           my $values = $conv->sdecode(Net::CSTAv3::Client::HiPath::CSTA_EventReport_Transferred(), $pdu);
462 0           $values->{'cross-ref-identifier'} = $conv->decode_xml2hextxt($values->{'cross-ref-identifier_orig'});
463 0           $values->{'call-id'} = $conv->decode_xml2hextxt($values->{'call-id_orig'});
464 0           $values->{'old-call-id'} = $conv->decode_xml2hextxt($values->{'old-call-id_orig'});
465 0           $values->{'dialing-number'} = $conv->decode_octet_string($values->{'dialing-number_orig'},$values->{'dialing-number_length'});
466 0           $values->{'transferring-device'} = $conv->decode_octet_string($values->{'transferring-device_orig'}, $values->{'transferring-device_length'});
467 0           $values->{'transferred-to-device'} = $conv->decode_octet_string($values->{'transferred-to-device_orig'}, $values->{'transferred-to-device_length'});
468 0           $values->{'endpoint'} = $conv->decode_octet_string($values->{'endpoint_orig'}, $values->{'endpoint_length'});
469              
470 0           $self->debug("EVENT RECEIVED: transferred event:\n");
471 0           $self->debug("> cross-ref-identifier: $values->{'cross-ref-identifier'}\n");
472 0           $self->debug("> call-id: $values->{'call-id'}\n");
473 0           $self->debug("> old-call-id: $values->{'old-call-id'}\n");
474 0           $self->debug("> transferring-device: $values->{'transferring-device'}\n");
475 0           $self->debug("> transferred-to-device: $values->{'transferred-to-device'}\n");
476 0           $self->debug("> endpoint: $values->{'endpoint'}\n");
477 0           $self->debug("> timestamp: $values->{'timestamp'}\n");
478              
479 0           $self->{'_active_monitorings'}->{$values->{'cross-ref-identifier'}}->{'transferred_cb'}->($values);
480              
481 0           return $values;
482             }
483              
484              
485              
486             sub send_csta_make_call {
487 0     0 0   my $self = $_[0];
488 0           my %args = %{$_[1]};
  0            
489              
490 0           my $conv = Convert::ASN1::asn1c->new();
491              
492 0           my $pdu = $conv->sencode(Net::CSTAv3::Client::HiPath::CSTA_MakeCall(), {
493             'calling-device'=>$conv->encode_octet_string($args{'calling-device'}, length($args{'calling-device'})),
494             'called-device'=>$conv->encode_octet_string($args{'called-device'}, length($args{'called-device'})),
495             'invoke-id'=>$conv->encode_integer($args{'invoke-id'}, 1),
496             'invoke-id_length'=>1, #TODO handle length correctly
497             });
498 0           $self->debug("SENDING CSTA-MakeCall\n");
499 0           $self->send_pdu($pdu);
500             }
501              
502             sub send_csta_set_display {
503 0     0 0   my $self = $_[0];
504 0           my %args = %{$_[1]};
  0            
505              
506 0           my $conv = Convert::ASN1::asn1c->new();
507              
508 0           my $pdu = $conv->sencode(Net::CSTAv3::Client::HiPath::CSTA_SetDisplay(), {
509             'device'=>$conv->encode_octet_string($args{'device'}, length($args{'device'})),
510             'text'=>$conv->encode_octet_string($args{'text'}, length($args{'text'})),
511             'invoke-id'=>$conv->encode_integer($args{'invoke-id'}, 1),
512             'invoke-id_length'=>1, #TODO handle length correctly
513             });
514 0           $self->debug("SENDING CSTA-SetDisplay\n");
515 0           $self->send_pdu($pdu);
516             }
517              
518              
519              
520             sub receive_csta_make_call_response {
521            
522 0     0 0   my $self = shift;
523 0           my $conv = Convert::ASN1::asn1c->new();
524 0           my $pdu = $self->receive_stuff();
525 0           my $values = $conv->sdecode(Net::CSTAv3::Client::HiPath::CSTA_MakeCallResponse(), $pdu);
526              
527 0           $self->debug("RECEIVED CSTA-MakeCallResponse\n");
528 0           $self->debug("> invoke-id: $values->{'invoke-id'}\n");
529 0           $self->debug("> operation-value: $values->{'operation-value'}\n");
530 0           $self->debug("> call-id: $values->{'call-id'}\n");
531 0           $self->debug("> dialing-number: $values->{'dialing-number'}\n");
532 0           return $values;
533              
534             }
535              
536             sub receive_csta_set_display_response {
537            
538 0     0 0   my $self = shift;
539 0           my $conv = Convert::ASN1::asn1c->new();
540 0           my $pdu = $self->receive_stuff();
541 0           my $values = $conv->sdecode(Net::CSTAv3::Client::HiPath::CSTA_SetDisplayResponse(), $pdu);
542              
543 0           $self->debug("RECEIVED CSTA-SetDisplayResponse\n");
544 0           $self->debug("> invoke-id: $values->{'invoke-id'}\n");
545 0           $self->debug("> operation-value: $values->{'operation-value'}\n");
546 0           return $values;
547              
548             }
549              
550             sub new {
551 0     0 1   my ($class_name) = @_;
552 0           my $self = {};
553 0           $self->{'_debug_state'} = 0;
554 0           bless ($self, $class_name);
555 0           return $self;
556             }
557              
558             sub debug_on {
559 0     0 1   my $self = shift;
560 0           $self->{'_debug_state'} = 1;
561             }
562              
563             sub debug_off {
564 0     0 1   my $self = shift;
565 0           $self->{'_debug_state'} = 0;
566             }
567              
568             sub get_socket {
569 0     0 0   my $self = shift;
570 0           return $self->{'_csta_socket'}
571             }
572              
573             sub main_loop {
574 0     0 1   my $self = shift;
575 0           while (1) {
576 0           my $pdu = $self->receive_stuff();
577 0           $self->parse_any_csta_packet($pdu);
578             }
579             }
580              
581              
582             1;
583             __END__