aboutsummaryrefslogtreecommitdiff
path: root/misc/OGM.pl
diff options
context:
space:
mode:
Diffstat (limited to 'misc/OGM.pl')
-rw-r--r--misc/OGM.pl353
1 files changed, 353 insertions, 0 deletions
diff --git a/misc/OGM.pl b/misc/OGM.pl
new file mode 100644
index 0000000..b89d197
--- /dev/null
+++ b/misc/OGM.pl
@@ -0,0 +1,353 @@
+#ver 0.06 (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 %calls;
+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 SystemStatusResult{
+ my $invokeID = shift;
+ my $pdu = $CSTAapdu->encode({svcResult=>{invokeID=>$invokeID,result=>{serviceID=>211,serviceResult=>{noData=>1}}}});
+ send_pdu($pdu); # send SystemStatus Result
+}
+sub playOGM{
+ my $ogmId = shift;
+ if (!$ogmId) {$ogmId=10}
+ my $connectionID = shift;
+ my $pdu = $CSTAapdu->encode({svcRequest=>{
+ invokeID=>11,
+ serviceID=>51,
+ serviceArgs=>{
+ privateData=>{
+ private =>{
+ kmeResourceControl=>{
+ ogmStart=>{
+ connection=>$connectionID,
+ ogmId=>$ogmId
+ }
+ }
+ }
+ }
+ }
+ }
+ });
+ send_pdu($pdu);
+}
+sub numberOfMsgPort{
+#EscapeArgument.privateData.private.kmeSystemData.getSystemData.request
+my $pdu = $CSTAapdu->encode({svcRequest=>{
+ invokeID=>8,
+ serviceID=>51,
+ serviceArgs=>{
+ privateData=>{
+ private =>{
+ kmeSystemData=>{
+ getSystemData=>{
+ request =>{
+ systemData=>18
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ });
+send_pdu($pdu);
+while (1) {
+ $pdu = receive_stuff();
+ my $out = $CSTAapdu->decode($pdu);
+ if (defined $out->{svcRequest}->{serviceArgs}->{privateData}->{private}->{kmeSystemData}->{systemDataLinkedReply}->{sysData}->{numberOfMsgPort}) {
+ my $MsgPorts = $out->{svcRequest}->{serviceArgs}->{privateData}->{private}->{kmeSystemData}->{systemDataLinkedReply}->{sysData}->{numberOfMsgPort};
+ return $MsgPorts
+ }
+ }
+}
+sub answer{
+ my $callerID = shift;
+ my $connectionID = shift;
+ my $MsgPorts = numberOfMsgPort();
+ #берём трубку
+ my $pdu = $CSTAapdu->encode({svcRequest=>{
+ invokeID=>10,
+ serviceID=>2,
+ serviceArgs=>{
+ callToBeAnswered=>$connectionID
+ }
+ }
+ });
+ send_pdu($pdu);
+ my $callID = $connectionID->{both}->{callID};
+ print "answered callID:",$callID," callerID:",$callerID, "\n";
+ my $numberOfFreePort = $MsgPorts->{numberOfFreePort};
+ print "numberOfFreePort:",$numberOfFreePort,"\n";
+ if (!$numberOfFreePort) {
+ my $pdu = $CSTAapdu->encode({svcRequest=>{
+ invokeID=>13,
+ serviceID=>5,
+ serviceArgs=>{
+ connectionToBeCleared=>$connectionID
+ }
+ }
+ });
+ send_pdu($pdu);
+ print "connection callID:",$callID," cleared\n";
+ next
+ }
+ my $digits = [split('',$callerID)];
+ $calls{$callID} = $digits;
+ print "digits in the array:", scalar @{$calls{$callID}}, "\n";
+ my $digit = shift @{$calls{$callID}};
+ playOGM($digit, $connectionID)
+}
+# parse ASN.1 desciptions
+my $asn = Convert::ASN1->new;
+$asn->prepare_file('d:\111\asn_perl\kxtde.asn') or die "prepare: ", $asn->error;
+my %serviceArgs = ( 2 => 'AnswerCallArgument',
+ 5 => 'ClearConnectionArgument',
+ 21=> 'CSTAEventReportArgument',
+ 51=> 'EscapeArgument',
+# 10=> 'MakeCallArgument',
+ 71=> 'MonitorStartArgument',
+ 211=> 'SystemStatusArg');
+foreach (keys %serviceArgs) {
+ $asn->registertype('serviceArgs',$_,$asn->find($serviceArgs{$_}));
+}
+my %serviceResults = ( 51=> 'EscapeResult',
+# 10=> 'MakeCallResult',
+ 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});
+my $Number=177; # ! ICD номер
+my $MsgPorts = numberOfMsgPort();
+print "numberOfMsgPort:", $MsgPorts->{numberOfMsgPort}, "\n";
+#EscapeArgument.privateData.private.kmeSystemData.setSystemData
+my $pdu = $CSTAapdu->encode({svcRequest=>{
+ invokeID=>9,
+ serviceID=>51,
+ serviceArgs=>{
+ privateData=>{
+ private =>{
+ kmeSystemData=>{
+ setSystemData=>{
+ acdQueue =>{
+ device =>{
+ deviceIdentifier=>{
+ dialingNumber=>$Number
+ }
+ },
+ attribute=>{
+ acdMode =>1
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ });
+send_pdu($pdu);
+#EscapeArgument.privateData.private.kmeSystemData.setSystemData
+$pdu = $CSTAapdu->encode({svcRequest=>{
+ invokeID=>9,
+ serviceID=>51,
+ serviceArgs=>{
+ privateData=>{
+ private =>{
+ kmeSystemData=>{
+ setSystemData=>{
+ acdQueue =>{
+ device =>{
+ deviceIdentifier=>{
+ dialingNumber=>$Number
+ }
+ },
+ attribute=>{
+ ctiWaitTime =>20
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ });
+send_pdu($pdu);
+#monitor
+$pdu = $CSTAapdu->encode({svcRequest=>{
+ invokeID=>9,
+ serviceID=>71,
+ serviceArgs=>{
+ monitorObject=>{
+ deviceObject=>{
+ deviceIdentifier=>{
+ dialingNumber=>$Number
+ }
+ }
+ },
+ requestedMonitorFilter=>{}
+ }
+ }
+ });
+send_pdu($pdu);
+while (1) {
+ $pdu = receive_stuff();
+ #Convert::ASN1::asn_dump($pdu);
+ my $out = $CSTAapdu->decode($pdu);
+ # $Data::Dumper::Indent=1;
+ # $Data::Dumper::Pair=' ';
+ # $Data::Dumper::Quotekeys=0;
+ # $Data::Dumper::Varname='CSTAapdu';
+ #print Dumper($out);
+ if (defined $out->{svcRequest}) {
+ my $serviceID = $out->{svcRequest}->{serviceID};
+ my $invokeID = $out->{svcRequest}->{invokeID};
+ my $serviceArgs=$out->{svcRequest}->{serviceArgs};
+ if ($serviceID==21) {
+ if (defined $serviceArgs->{eventSpecificInfo}->{callControlEvents}->{delivered}) {
+ my $connectionID = $serviceArgs->{eventSpecificInfo}->{callControlEvents}->{delivered}->{connection};
+ if (defined $serviceArgs->{eventSpecificInfo}->{callControlEvents}->{delivered}->{callingDevice}->{deviceIdentifier}->{deviceIdentifier}->{dialingNumber}) {
+ my $callerID = $serviceArgs->{eventSpecificInfo}->{callControlEvents}->{delivered}->{callingDevice}->{deviceIdentifier}->{deviceIdentifier}->{dialingNumber};
+ answer($callerID, $connectionID);
+ } elsif ($serviceArgs->{eventSpecificInfo}->{callControlEvents}->{delivered}->{extensions}->{privateData}[0]->{private}->{kmeAdditionalData}->{device}->{deviceIdentifier}->{other}) {
+ my $callerID = $serviceArgs->{eventSpecificInfo}->{callControlEvents}->{delivered}->{extensions}->{privateData}[0]->{private}->{kmeAdditionalData}->{device}->{deviceIdentifier}->{other};
+ substr($callerID, 0, 1) = "";
+ answer($callerID, $connectionID);
+ }
+ else {print "not number\n"}
+ } elsif ($serviceArgs->{eventSpecificInfo}->{callControlEvents}->{transferred}) {
+ my $callID = $serviceArgs->{eventSpecificInfo}->{callControlEvents}->{transferred}->{transferredConnections}[0]->{newConnection}->{both}->{callID};
+ my $oldCallID = $serviceArgs->{eventSpecificInfo}->{callControlEvents}->{transferred}->{primaryOldCall}->{both}->{callID};
+ $calls{$callID} = $calls{$oldCallID};
+ delete $calls{$oldCallID};
+ print "transferred: new callID:",$callID,"\n";
+ } elsif (defined $serviceArgs->{eventSpecificInfo}->{vendorSpecEvents}->{privateEvent}->{privateData}->{private}->{kmePrivateEvent}->{ogmStatus}) {
+ my $ogmStatus=$serviceArgs->{eventSpecificInfo}->{vendorSpecEvents}->{privateEvent}->{privateData}->{private}->{kmePrivateEvent}->{ogmStatus};
+ print "ogmPortNumber:",$ogmStatus->{ogmPortNumber}->{deviceIdentifier}->{deviceNumber} & 0xFFFF;
+ print " ogmId:",$ogmStatus->{ogmId};
+ if ($ogmStatus->{state}) {
+ print " state:stop\n";
+ my $connectionID = $ogmStatus->{connection};
+ my $callID = $connectionID->{both}->{callID};
+ if (scalar @{$calls{$callID}}) {
+ print "digits in the array:", scalar @{$calls{$callID}}, "\n";
+ my $digit = shift @{$calls{$callID}};
+ playOGM($digit, $connectionID)
+ } else {
+ delete $calls{$callID};
+ # кладём трубку
+ my $pdu = $CSTAapdu->encode({svcRequest=>{
+ invokeID=>13,
+ serviceID=>5,
+ serviceArgs=>{
+ connectionToBeCleared=>$connectionID
+ }
+ }
+ });
+ send_pdu($pdu);
+ print "connection callID:",$callID," cleared\n"
+ }
+ }
+ else {print " state:start\n"}
+ }
+ } elsif ($serviceID==211) { # if SystemStatus Request
+ SystemStatusResult($invokeID);
+ }
+
+ }
+} \ No newline at end of file