use POSIX; use Carp; #use Data::Dumper; use IO::Socket; sub decode_msg_header { my $bin = shift; my $len = unpack('n', $bin); return $len; } sub encode_msg_header { my $len = shift; # print("len: [$len]\n"); die "Message larger than allowed!" unless ($len <= 240); my $bin = pack('n', $len); return $bin; } sub convert_to_hex { my $pdu = $_[0]; my $hexdata = unpack('H*', $pdu); $hexdata =~ tr/a-z/A-Z/; $hexdata =~ s/(..)/$1 /g; $hexdata =~ s/ $//g; return $hexdata; } sub send_pdu { my $pdu = $_[0]; my $header = encode_msg_header(length($pdu)); $socket->write($header); $headerdata = convert_to_hex($header); # print("SENT HEADER: [$headerdata]\n"); $socket->write($pdu); $hexdata = convert_to_hex($pdu); # print("SENT: [$hexdata]\n"); } sub csta_connect { my %args = %{$_[0]}; open_csta_socket($args{host}, $args{port}); # A-ASSOCIATE Request my $pdu = "602380020780A10706052B0C00815ABE14281206072B0C00821D8148A007A0050303000800"; $pdu = pack('H*', $pdu); send_pdu($pdu); # A-ASSOCIATE Result receive_stuff(); } sub open_csta_socket { my $host = shift; my $port = shift; # print("trying to open a connection to $host on port $port\n"); $socket = new IO::Socket::INET( PeerAddr => $host, PeerPort => $port, Blocking => 1, Proto => 'tcp') || die "Error creating socket: $!\n"; $socket->autoflush(1); print("opened a connection to $host on port $port\n"); } sub receive_stuff { my $header = ''; my $pdu = ''; my $nbytes = $socket->sysread($header, 2); if ($nbytes==1) { # фрагмент пакета # print("RECEIVED fragment".chr(7)."\n"); $nbytes2= $socket->sysread($header2, 1); $header = $header.$header2; $nbytes = 2; } croak "Didn't receive the specified amount of data (2 bytes)!\n".chr(7) unless ($nbytes == 2); # print("Received 2 bytes, assuming it's a data length\n"); my $len = decode_msg_header($header); # print("Waiting for [$len] bytes of ASN1 data now\n"); $nbytes = $socket->sysread($pdu, $len); if ($nbytes<$len) { # фрагмент пакета # print("RECEIVED fragment".chr(7)."\n"); $nbytes2= $socket->sysread($pdu2, $len-$nbytes); $pdu = $pdu.$pdu2; $nbytes = $nbytes + $nbytes2; } croak "Didn't receive the specified amount of data ($len bytes)!\n".chr(7) unless ($nbytes == $len); my $hexdata = convert_to_hex($pdu); # print("RECEIVED:[$hexdata]\n"); return $pdu; } sub main_loop { while (1) { my $pdu = receive_stuff(); my $hexdata = convert_to_hex($pdu); # If SystemStatus Request if ($hexdata =~/A1 0C 02 01 .. 02 02 00 D3 30 03 0A 01 02/) { # SystemStatus Response my $pdu = "A20B0201".substr($hexdata, 12, 2)."3006020200D30500"; $pdu = pack('H*', $pdu); send_pdu($pdu); } # If SystemStatus Request 2 elsif ($hexdata =~/A1 0D 02 02 .. .. 02 02 00 D3 30 03 0A 01 02/){ # SystemStatus Response 2 my $pdu = "A20C0202".substr($hexdata, 12, 2).substr($hexdata, 15, 2)."3006020200D30500"; $pdu = pack('H*', $pdu); send_pdu($pdu); } # if localConnectionInfo=alerting and cause=newCall|distributed elsif ($hexdata =~m/4E 01 02 0A 01 [12]6/) { # звонок от if ($hexdata =~m/61 .. 30 .. 80 /) { $num = hex(substr($', 0, 2)); $str = substr($', 3, $num*3); $str =~s/\s//g; $CallerID=pack ("H*", $str); } else { $CallerID="CO".substr($hexdata, length($hexdata)-2, 2); } # звонок кому if ($hexdata =~m/63 .. 30 .. 80 /) { $num = hex(substr($', 0, 2)); $str = substr($', 3, $num*3); $str =~s/\s//g; $CalledID=pack ("H*", $str); } print strftime("%H:%M:%S ", localtime); print("Call to:$CalledID from:$CallerID\n"); } } } sub MonitorStart{ my $ext = shift; $ext =~s/(.)/sprintf("%02x",ord($1))/eg; my $pdu = "A111020178020147300930058003".$ext."A000"; $pdu = pack('H*', $pdu); send_pdu($pdu); $pdu = receive_stuff(); } csta_connect({'host'=>'192.168.0.101', 'port'=>33333}); for ($ext_num = 101; $ext_num <=156; $ext_num++){ MonitorStart($ext_num); } main_loop();