aboutsummaryrefslogtreecommitdiff
path: root/_misc/monitorCallerID2.pl
diff options
context:
space:
mode:
Diffstat (limited to '_misc/monitorCallerID2.pl')
-rw-r--r--_misc/monitorCallerID2.pl261
1 files changed, 261 insertions, 0 deletions
diff --git a/_misc/monitorCallerID2.pl b/_misc/monitorCallerID2.pl
new file mode 100644
index 0000000..d39c38f
--- /dev/null
+++ b/_misc/monitorCallerID2.pl
@@ -0,0 +1,261 @@
+#ver 0.02 (C)Cyr
+use strict;
+use warnings;
+use diagnostics;
+use IO::Socket;
+use Convert::ASN1;
+use Data::Dumper;
+use Carp;
+use POSIX;
+my $CSTAapdu;
+my $socket;
+my @devices;
+sub deviceNumber{
+ my $deviceNumber = shift;
+ my $deviceType = $deviceNumber & 0xFFFF0000;
+ if ($deviceType==0x1310000) {
+ $deviceType='CO'
+ } elsif ($deviceType==0x1210000) {
+ $deviceType='PS'
+ } elsif ($deviceType==0x1110000) {
+ $deviceType='EXT'
+ } elsif ($deviceType==0x1550000) {
+ $deviceType='DISA'
+ }
+ $deviceNumber = $deviceNumber & 0x0000FFFF;
+ return $deviceType.sprintf("%03s",$deviceNumber);
+}
+sub decode_msg_header {
+ my $bin = shift;
+ my $len = unpack('n', $bin);
+ return $len;
+}
+sub encode_msg_header {
+ my $len = shift;
+ 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);
+ $socket->write($pdu);
+# my $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
+ $pdu = receive_stuff();
+ my $hexdata = convert_to_hex($pdu);
+ if ($hexdata =~/A2 03 02 01 01/){
+ print "rejected-permanent\n";
+ exit 0
+ }
+ #SystemStatus Request
+ $pdu = receive_stuff();
+ my $out = $CSTAapdu->decode($pdu);
+ my $invokeID = $out->{svcRequest}->{invokeID};
+ SystemStatusResult($invokeID);
+}
+
+sub open_csta_socket {
+ my $host = shift;
+ my $port = shift;
+ $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) { # фрагмент пакета
+ my $header2;
+ my $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);
+ my $len = decode_msg_header($header);
+ $nbytes = $socket->sysread($pdu, $len);
+ if ($nbytes<$len) { # фрагмент пакета
+ my $pdu2;
+ my $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 GetSystemData{
+ my $DeviceCategory = shift;
+ #EXT=5
+ #CO =2
+ my $pdu = $CSTAapdu->encode({svcRequest=>{
+ invokeID=>4,
+ serviceID=>51,
+ serviceArgs=>{
+ privateData=>{
+ private=>{
+ kmeSystemData=>{
+ getSystemData=>{
+ request=>{
+ deviceList=>{
+ category=>{
+ standardDevice=>$DeviceCategory
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ });
+ #my $pdu = "A11602020602020133300DA40BA009A407A105A0030A010".$DeviceCategory;
+ #$pdu = pack('H*', $pdu);
+ send_pdu($pdu);
+ # getSystemDataPosAck
+ $pdu = receive_stuff();
+ my $out = $CSTAapdu->decode($pdu);
+ my $crossRefID = $out->{svcResult}->{result}->{serviceResult}->{extensions}->{privateData}[0]->{private}->{kmeSystemData}->{getSystemDataPosAck};
+ my $lastSegment=0;
+ # systemDataLinkedReply
+ while (!$lastSegment) {
+ $pdu = receive_stuff();
+ my $out = $CSTAapdu->decode($pdu);
+ my $systemDataLinkedReply = $out->{svcRequest}->{serviceArgs}->{privateData}->{private}->{kmeSystemData}->{systemDataLinkedReply};
+ if (defined $systemDataLinkedReply) {
+ if ($systemDataLinkedReply->{crossRefID} cmp $crossRefID) {next}
+ $lastSegment = $systemDataLinkedReply->{lastSegment};
+ foreach my $KmeDeviceStateEntry (@{$systemDataLinkedReply->{sysData}->{deviceList}}) {
+ if ($KmeDeviceStateEntry->{status}==0) {
+# print "device:",$KmeDeviceStateEntry->{number},"\n";
+ push @devices, ($KmeDeviceStateEntry->{device}->{deviceIdentifier}->{deviceNumber});
+ }
+ }
+ }
+ }
+}
+sub MonitorStartArgument{
+my $device = shift;
+my $pdu = $CSTAapdu->encode({svcRequest=>{
+ invokeID=>9,
+ serviceID=>71,
+ serviceArgs=>{
+ monitorObject=>{
+ deviceObject=>{
+ deviceIdentifier=>{
+ deviceNumber=>$device
+ }
+ }
+ },
+ requestedMonitorFilter=>{}
+ }
+ }
+ });
+send_pdu($pdu);
+#$pdu = receive_stuff();
+}
+sub CSTAEventReportArgument{
+my $refeventSpecificInfo = shift;
+if (defined $refeventSpecificInfo->{eventSpecificInfo}->{callControlEvents}) {
+ my $refcallControlEvents = $refeventSpecificInfo->{eventSpecificInfo}->{callControlEvents};
+ my $callControlEvents = (keys %{$refcallControlEvents})[0];
+ my $Event = $refcallControlEvents->{$callControlEvents};
+ #print Dumper($refcallControlEvents);
+ if ((($Event->{localConnectionInfo}==2) & (($Event->{cause}==22) | ($Event->{cause}==38))) |
+ (($Event->{localConnectionInfo}==3) & ($Event->{cause}==74))) {
+ #localConnectionInfo = allerting and cause=newCall|distributed
+ my $CalledID = deviceID($Event->{alertingDevice}->{deviceIdentifier});
+ my $CallerID;
+ if (defined $Event->{callingDevice}->{notKnown}) {
+ $CallerID = deviceID($Event->{associatedCallingDevice}->{deviceIdentifier})
+ } else {
+ $CallerID = deviceID($Event->{callingDevice}->{deviceIdentifier})
+ }
+ print strftime("%H:%M:%S ", localtime);
+ print("Call to:$CalledID from:$CallerID\n");
+ }
+ }
+}
+sub deviceID{
+ my $deviceIdentifier = shift;
+ $deviceIdentifier = $deviceIdentifier->{deviceIdentifier};
+ if (defined $deviceIdentifier->{dialingNumber}) {
+ return $deviceIdentifier->{dialingNumber}
+ } elsif (defined $deviceIdentifier->{deviceNumber}) {
+ return deviceNumber($deviceIdentifier->{deviceNumber})
+ } elsif (defined $deviceIdentifier->{other}) {
+ return $deviceIdentifier->{other}
+ }
+}
+sub SystemStatusResult{
+ my $invokeID = shift;
+ my $pdu = $CSTAapdu->encode({svcResult=>{invokeID=>$invokeID,result=>{serviceID=>211,serviceResult=>{noData=>1}}}});
+ send_pdu($pdu); # send SystemStatus Result
+}
+$Data::Dumper::Indent=1;
+$Data::Dumper::Pair=' ';
+$Data::Dumper::Quotekeys=0;
+$Data::Dumper::Varname='calls';
+# parse ASN.1 desciptions
+my $asn = Convert::ASN1->new;
+#$asn->configure(tagdefault=>'EXPLICIT');
+$asn->prepare_file('d:\111\asn_perl\kxtde.asn') or die "prepare: ", $asn->error;
+my %serviceArgs = ( 21=> 'CSTAEventReportArgument',
+ 51=> 'EscapeArgument',
+ 71=> 'MonitorStartArgument',
+ 211=> 'SystemStatusArg');
+foreach (keys %serviceArgs) {
+ $asn->registertype('serviceArgs',$_,$asn->find($serviceArgs{$_}));
+}
+my %serviceResults = ( 51=> 'EscapeResult',
+ 71=> 'MonitorStartResult',
+ 211=> 'SystemStatusRes');
+foreach (keys %serviceResults) {
+ $asn->registertype('serviceResult',$_,$asn->find($serviceResults{$_}));
+}
+$CSTAapdu = $asn->find('CSTAapdu');
+csta_connect({'host'=>'192.168.0.101', 'port'=>33333});
+GetSystemData(2);
+GetSystemData(5);
+foreach my $number (@devices) {
+ MonitorStartArgument($number);
+}
+while (1) {
+ my $pdu = receive_stuff();
+ my $out = $CSTAapdu->decode($pdu);
+ if (defined $out->{svcRequest}) {
+ my $serviceID = $out->{svcRequest}->{serviceID};
+ my $invokeID = $out->{svcRequest}->{invokeID};
+ my $serviceArgs = $out->{svcRequest}->{serviceArgs};
+ if ($serviceID==21) {
+ CSTAEventReportArgument($serviceArgs);
+ } elsif ($serviceID==211) { # if SystemStatus Request
+ SystemStatusResult($invokeID);
+ }
+ }
+}