aboutsummaryrefslogtreecommitdiff
path: root/_misc
diff options
context:
space:
mode:
Diffstat (limited to '_misc')
-rw-r--r--_misc/OGM.pl452
-rw-r--r--_misc/codes.go170
-rw-r--r--_misc/kxtde.asn826
-rw-r--r--_misc/main.go251
-rw-r--r--_misc/makecall.pl358
-rw-r--r--_misc/monitorCallerID.pl174
-rw-r--r--_misc/monitorCallerID2.pl261
-rwxr-xr-x_misc/monitorTDE2.pl299
-rwxr-xr-x_misc/snapshot.pl538
-rw-r--r--_misc/tde.c366
10 files changed, 3695 insertions, 0 deletions
diff --git a/_misc/OGM.pl b/_misc/OGM.pl
new file mode 100644
index 0000000..0d4e973
--- /dev/null
+++ b/_misc/OGM.pl
@@ -0,0 +1,452 @@
+#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);
+ }
+
+ }
+}
diff --git a/_misc/codes.go b/_misc/codes.go
new file mode 100644
index 0000000..075fe1c
--- /dev/null
+++ b/_misc/codes.go
@@ -0,0 +1,170 @@
+package main
+
+var phoneCodes = map[int]string{
+ 0x01000000: `SLT`,
+ 0x02000001: `APT KX-T7020/7320/7720`,
+ 0x02000003: `APT KX-T123220`,
+ 0x02020001: `APT KX-T7030/7033/7330/7730`,
+ 0x02020002: `APT KX-T123235/T7130`,
+ 0x02020003: `APT KX-T123230/TD7895/T7885`,
+ 0x02020005: `APT KX-T7735`,
+ 0x02030001: `APT KX-T7030/7033/7330/7730`,
+ 0x02030002: `APT KX-T123235/T7130`,
+ 0x02030003: `APT KX-T123230`,
+ 0x02030005: `APT KX-T7735`,
+ 0x02040001: `APT KX-T7050/7350/7750`,
+ 0x02040003: `APT KX-T123250`,
+ 0x02080003: `APT KX-T61620`,
+ 0x02090003: `APT KX-T61650`,
+ 0x020a0003: `APT KX-T61630/31`,
+ 0x020b0003: `APT KX-T61630/31`,
+ 0x020c0003: `APT KX-T30820/25`,
+ 0x020d0000: `APT KX-T30850/T7055`,
+ 0x020d0003: `APT KX-T7894 (Wireless)`,
+ 0x020e0003: `APT KX-T30830`,
+ 0x020f0003: `APT KX-T30830`,
+ 0x03000000: `Old DPT KX-T7235`,
+ 0x03000001: `Old DPT KX-T7x36`,
+ 0x03000002: `Old DPT KX-T7536`,
+ 0x03000012: `Old DPT KX-T7536+12CO`,
+ 0x03000801: `Old DPT KX-T7436`,
+ 0x03000802: `Old DPT KX-T7536`,
+ 0x03000812: `Old DPT KX-T7536+12CO`,
+ 0x03010000: `Old DPT KX-T7230`,
+ 0x03010001: `Old DPT KX-T7433`,
+ 0x03010002: `Old DPT KX-T7533`,
+ 0x03010003: `Old DPT KX-T7431`,
+ 0x03010004: `Old DPT KX-T7531`,
+ 0x03010012: `Old DPT KX-T7533+12CO`,
+ 0x03010014: `Old DPT KX-T7531+12CO`,
+ 0x03010801: `Old DPT KX-T7433`,
+ 0x03010802: `Old DPT KX-T7533`,
+ 0x03010803: `Old DPT KX-T7431`,
+ 0x03010804: `Old DPT KX-T7531/7565`,
+ 0x03010812: `Old DPT KX-T7533+12CO`,
+ 0x03010814: `Old DPT KX-T7531+12CO`,
+ 0x03018804: `Old DPT KX-T7565`,
+ 0x03040000: `Old DPT KX-T7250`,
+ 0x03040001: `Old DPT KX-T7420`,
+ 0x03040002: `Old DPT KX-T7450`,
+ 0x03040003: `Old DPT KX-T7520`,
+ 0x03040004: `Old DPT KX-T7550/7560`,
+ 0x03040013: `Old DPT KX-T7520+12CO`,
+ 0x03040014: `Old DPT KX-T7550+12CO`,
+ 0x03040801: `Old DPT KX-T7420`,
+ 0x03040802: `Old DPT KX-T7450`,
+ 0x03040803: `Old DPT KX-T7520`,
+ 0x03040804: `Old DPT KX-T7550`,
+ 0x03040813: `Old DPT KX-T7520+12CO`,
+ 0x03040814: `Old DPT KX-T7550+12CO`,
+ 0x03048004: `Old DPT KX-T7560`,
+ 0x03050000: `Old DPT KX-T7220/7451`,
+ 0x03050001: `Old DPT KX-T7425`,
+ 0x03050801: `Old DPT KX-T7425`,
+ 0x05000000: `Old DSSConsole KX-T123240`,
+ 0x05040000: `Old DSSConsole KX-T61640`,
+ 0x06000001: `New DSSConsole KX-T7440`,
+ 0x06000002: `New DSSConsole KX-T7441`,
+ 0x06000005: `New DSSConsole KX-T7540`,
+ 0x06000006: `New DSSConsole KX-T7541`,
+ 0x06050001: `New DSSConsole KX-T7640`,
+ 0x07100000: `Old format VPS (PCC)`,
+ 0x07100001: `Old format VPS (TVS75)`,
+ 0x07100002: `Old format VPS (TVS100)`,
+ 0x07200000: `New format VPS (PCC)`,
+ 0x08100000: `New DPT KX-T7625`,
+ 0x08100001: `New DPT KX-T7630`,
+ 0x08100002: `New DPT KX-T7633`,
+ 0x08100012: `New DPT KX-T7633+12CO`,
+ 0x08100022: `New DPT KX-T7633+USB`,
+ 0x08100032: `New DPT KX-T7633+12CO+USB`,
+ 0x08100003: `New DPT KX-T7636`,
+ 0x08100013: `New DPT KX-T7636+12CO`,
+ 0x08100023: `New DPT KX-T7636+USB`,
+ 0x08100033: `New DPT KX-T7636+12CO+USB`,
+ 0x08100004: `New DPT KX-T7665`,
+ 0x09100003: `IP-PT KX-NT136`,
+ 0x09100004: `IP-PT KX-NT265`,
+ 0x09100005: `IP-PT KX-NT265 Multi`,
+ 0x09100006: `IP-PT KX-NT343`,
+ 0x09100007: `IP-PT KX-NT346`,
+ 0x09100008: `IP-PT KX-NT366`,
+ 0x0a000000: `PS KX-TD7500CE (for TD PBX)`,
+ 0x0a000001: `PS KX-TD7590CE (for TD PBX)`,
+ 0x0a000010: `PS KX-TD7690 (2.4G SS: for TDA PBX)`,
+ 0x0a000020: `PS KX-TD7590CE (DECT: for TDA PBX)`,
+ 0x0a000080: `PS Other Manufacturer`,
+ 0x0a000081: `PS KX-TCD706 ISDN compliant PS`,
+ 0x0a000082: `PS KX-TCD706 ISDN compliant PS (with data)`,
+ 0x0a000083: `PS KX-TCD7580`,
+ 0x0e000001: `ISDN`,
+ 0x0e000002: `OPX`,
+ 0x0fffffff: `Not registered`,
+}
+
+var keyCodes = map[int]string{
+ 0x00: `Not stored key`,
+ 0x02: `ICD Group (GDN)`,
+ 0x03: `Single-CO`,
+ 0x04: `Group-CO`,
+ 0x05: `Loop-CO`,
+ 0x11: `DSS`,
+ 0x10: `Onetouch Dial`,
+ 0x13: `Save`,
+ 0x14: `Redial`,
+ 0x20: `Fwd/DND (Both)`,
+ 0x21: `Fwd/DND (External)`,
+ 0x22: `Fwd/DND (Internal)`,
+ 0x23: `Group Fwd/DND (Both)`,
+ 0x24: `Group Fwd/DND (External)`,
+ 0x25: `Group Fwd/DND (Internal)`,
+ 0x26: `TRS Level Change`,
+ 0x30: `Conference`,
+ 0x31: `Hold&Paging`,
+ 0x32: `Call Park`,
+ 0x33: `Park&Paging`,
+ 0x40: `Answer`,
+ 0x42: `Release`,
+ 0x43: `Terminate`,
+ 0x44: `EFA`,
+ 0x50: `ISDN Service`,
+ 0x51: `ISDN-Hold`,
+ 0x60: `Voice Mail Transfer`,
+ 0x61: `Two Way Record`,
+ 0x62: `Two Way Transfer`,
+ 0x63: `Live Call Screen (LCS)`,
+ 0x70: `Wake Up Alert`,
+ 0x71: `Wake Up Set`,
+ 0x72: `Check In`,
+ 0x73: `Check Out`,
+ 0x74: `Clean Up`,
+ 0x80: `Message Waiting`,
+ 0x81: `Account`,
+ 0x82: `Emergency Paging`,
+ 0x83: `Queue Redirection`,
+ 0x91: `Log-in/Log-out`,
+ 0x92: `Wrap Up`,
+ 0x93: `CLIR`,
+ 0x94: `COLR`,
+ 0x95: `Headset`,
+ 0x96: `Time Service`,
+ 0xa0: `Call Log`,
+ 0xa1: `Charge`,
+ 0xa2: `System Alarm`,
+ 0x87: `CTI`,
+}
+
+var pbxType = map[int]string{
+ 0: `TDA100`,
+ 1: `TDA200`,
+ 2: `TDA30`,
+ 3: `TDA50`,
+ 5: `TDA15`,
+ 6: `TDA600`,
+ 7: `TDE100`,
+ 8: `TDE200`,
+ 9: `TDE600`,
+ 10: `NCP500`,
+ 11: `NCP1000`,
+ 12: `NCP3000`,
+}
diff --git a/_misc/kxtde.asn b/_misc/kxtde.asn
new file mode 100644
index 0000000..f44b279
--- /dev/null
+++ b/_misc/kxtde.asn
@@ -0,0 +1,826 @@
+-- ver 0.3 (C)Cyr
+CSTAapdu ::= CHOICE {
+ svcRequest ROIVapdu,
+ svcResult RORSapdu,
+ svcError ROERapdu
+-- svcReject RORJapdu
+}
+ROIVapdu ::= [1] IMPLICIT SEQUENCE {
+ invokeID INTEGER,
+ serviceID INTEGER,
+ serviceArgs ANY DEFINED BY serviceID
+}
+RORSapdu ::= [2] IMPLICIT SEQUENCE {
+ invokeID INTEGER,
+ result SEQUENCE {
+ serviceID INTEGER,
+ serviceResult ANY DEFINED BY serviceID OPTIONAL
+ }
+}
+ROERapdu ::= [3] IMPLICIT SEQUENCE {
+ invokeID INTEGER,
+ code INTEGER, -- local:1
+ parameter UniversalFailure
+}
+UniversalFailure ::= CHOICE
+{ operation [0] EXPLICIT OperationErrors,
+ stateIncompatibility [2] EXPLICIT StateIncompatibilityErrors,
+ systemResourceAvailability [3] EXPLICIT SystemResourceAvailabilityErrors,
+ unspecified [7] UnspecifiedErrors
+}
+OperationErrors ::= ENUMERATED
+{ invalidAgentGroup (32),
+ invalidAgentState (35),
+ invalidCalledDeviceID (6),
+ invalidConnectionID (13),
+ invalidDeviceID (12),
+ invalidParameterValue (31),
+ notSameDevice (86),
+ privilegeViolationSpecifiedDevice (8),
+ requestIncompatibleWithObject (2),
+ serviceNotSupported (50)
+}
+StateIncompatibilityErrors ::= ENUMERATED
+{
+ invalidObjectState (2)
+}
+SystemResourceAvailabilityErrors ::= ENUMERATED
+{
+ deviceOutOfService (15),
+ resourceBusy (2),
+ resourceLimitExceeded (26),
+ resourceOutOfService (4)
+}
+UnspecifiedErrors ::= NULL
+
+systemStatus ::= CHOICE
+{ ARGUMENT SystemStatusArg,
+ RESULT SystemStatusRes
+-- ERRORS {universalFailure}
+-- CODE local: 211
+}
+SystemStatusArg ::= SEQUENCE
+{ systemStatus SystemStatus}
+
+SystemStatusRes ::= CHOICE
+{ noData NULL}
+
+SystemStatus ::= ENUMERATED
+{ normal (2),
+ messageLost (3),
+ overloadReached (6)
+}
+monitorStart ::= CHOICE
+{ ARGUMENT MonitorStartArgument,
+ RESULT MonitorStartResult
+-- ERRORS {universalFailure}
+-- CODE local: 71
+}
+
+MonitorStartArgument ::= SEQUENCE
+{ monitorObject MonitorObject,
+ requestedMonitorFilter [0] IMPLICIT MonitorFilter OPTIONAL
+}
+
+MonitorStartResult ::= SEQUENCE
+{ crossRefIdentifier MonitorCrossRefID,
+ actualmonitorFilter [0] IMPLICIT MonitorFilter OPTIONAL
+}
+
+MonitorObject ::= CSTAObject
+
+CSTAObject ::= CHOICE
+{ deviceObject DeviceID,
+ callObject ConnectionID}
+
+MonitorFilter ::= SEQUENCE -- default is no filter (i.e. all events)
+{ callControl [0] IMPLICIT CallControlEvents OPTIONAL,
+-- callAssociated [6] IMPLICIT CallAssociatedEvents OPTIONAL,
+ physicalDeviceFeature [8] IMPLICIT PhysicalDeviceFeatureEvents OPTIONAL,
+ logicalDeviceFeature [9] IMPLICIT LogicalDeviceFeatureEvents OPTIONAL,
+-- maintenance [3] IMPLICIT DeviceMaintenanceEvents OPTIONAL,
+ private [4] IMPLICIT VendorSpecEvents OPTIONAL
+}
+
+cSTAEventReport ::= CHOICE
+{ ARGUMENT CSTAEventReportArgument
+-- ALWAYS RESPONDS FALSE
+-- CODE local:21
+}
+CSTAEventReportArgument ::= SEQUENCE
+{ crossRefIdentifier MonitorCrossRefID,
+ eventSpecificInfo EventSpecificInfo}
+
+EventSpecificInfo ::= CHOICE
+{ callControlEvents [0] CallControlEvents,
+-- callAssociatedEvents [1] CallAssociatedEvents,
+-- mediaAttachmentEvents [2] MediaAttachmentEvents,
+ physicalDeviceFeatureEvents [3] PhysicalDeviceFeatureEvents,
+ logicalDeviceFeatureEvents [4] LogicalDeviceFeatureEvents,
+-- deviceMaintenanceEvents [5] DeviceMaintenanceEvents,
+-- voiceUnitEvents [6] VoiceUnitEvents,
+ vendorSpecEvents [7] VendorSpecEvents
+}
+CallControlEvents ::= CHOICE
+{
+ conferenced [ 2] IMPLICIT ConferencedEvent,
+ connectionCleared [ 3] IMPLICIT ConnectionClearedEvent,
+ delivered [ 4] IMPLICIT DeliveredEvent,
+-- digitsDialed [ 5] IMPLICIT DigitsDialedEvent,
+ diverted [ 6] IMPLICIT DivertedEvent,
+ established [ 7] IMPLICIT EstablishedEvent,
+ failed [ 8] IMPLICIT FailedEvent,
+ held [ 9] IMPLICIT HeldEvent,
+ networkReached [11] IMPLICIT NetworkReachedEvent,
+ originated [13] IMPLICIT OriginatedEvent,
+ queued [14] IMPLICIT QueuedEvent,
+ retrieved [15] IMPLICIT RetrievedEvent,
+ serviceInitiated [16] IMPLICIT ServiceInitiatedEvent,
+ transferred [17] IMPLICIT TransferredEvent
+}
+ConferencedEvent ::= SEQUENCE
+{ primaryOldCall ConnectionID,
+ secondaryOldCall ConnectionID OPTIONAL,
+ conferencingDevice SubjectDeviceID,
+ addedParty SubjectDeviceID,
+ conferenceConnections ConnectionList,
+ localConnectionInfo LocalConnectionState OPTIONAL,
+ cause EventCause
+-- extensions [5] IMPLICIT CSTACommonArguments OPTIONAL
+}
+ConnectionClearedEvent ::= SEQUENCE
+{ droppedConnection ConnectionID,
+ releasingDevice SubjectDeviceID,
+ localConnectionInfo LocalConnectionState OPTIONAL,
+ cause EventCause
+-- extensions CSTACommonArguments OPTIONAL
+}
+DeliveredEvent ::= SEQUENCE
+{ connection ConnectionID,
+ alertingDevice SubjectDeviceID,
+ callingDevice CallingDeviceID,
+ calledDevice CalledDeviceID,
+ lastRedirectionDevice RedirectionDeviceID,
+ localConnectionInfo LocalConnectionState OPTIONAL,
+ cause EventCause,
+ networkCallingDevice NetworkCallingDeviceID OPTIONAL,
+ networkCalledDevice NetworkCalledDeviceID OPTIONAL,
+ associatedCallingDevice AssociatedCallingDeviceID OPTIONAL,
+ associatedCalledDevice AssociatedCalledDeviceID OPTIONAL,
+ extensions CSTACommonArguments OPTIONAL
+}
+DivertedEvent ::= SEQUENCE
+{ connection ConnectionID,
+ divertingDevice SubjectDeviceID,
+ newDestination SubjectDeviceID,
+ callingDevice CallingDeviceID OPTIONAL,
+ calledDevice CalledDeviceID OPTIONAL,
+ lastRedirectionDevice RedirectionDeviceID,
+ localConnectionInfo LocalConnectionState OPTIONAL,
+ cause EventCause,
+ networkCallingDevice NetworkCallingDeviceID OPTIONAL,
+ networkCalledDevice NetworkCalledDeviceID OPTIONAL,
+ associatedCallingDevice AssociatedCallingDeviceID OPTIONAL,
+ associatedCalledDevice AssociatedCalledDeviceID OPTIONAL
+}
+EstablishedEvent ::= SEQUENCE
+{ establishedConnection ConnectionID,
+ answeringDevice SubjectDeviceID,
+ callingDevice CallingDeviceID,
+ calledDevice CalledDeviceID,
+ lastRedirectionDevice RedirectionDeviceID,
+ localConnectionInfo LocalConnectionState OPTIONAL,
+ cause EventCause,
+ networkCallingDevice NetworkCallingDeviceID OPTIONAL,
+ networkCalledDevice NetworkCalledDeviceID OPTIONAL,
+ associatedCallingDevice AssociatedCallingDeviceID OPTIONAL,
+ associatedCalledDevice AssociatedCalledDeviceID OPTIONAL,
+ extensions CSTACommonArguments OPTIONAL
+}
+FailedEvent ::= SEQUENCE
+{ failedConnection ConnectionID,
+ failingDevice SubjectDeviceID,
+ callingDevice CallingDeviceID,
+ calledDevice CalledDeviceID,
+ lastRedirectionDevice RedirectionDeviceID,
+ localConnectionInfo LocalConnectionState OPTIONAL,
+ cause EventCause,
+ networkCallingDevice NetworkCallingDeviceID OPTIONAL,
+ networkCalledDevice NetworkCalledDeviceID OPTIONAL,
+ associatedCallingDevice AssociatedCallingDeviceID OPTIONAL,
+ associatedCalledDevice AssociatedCalledDeviceID OPTIONAL
+}
+HeldEvent ::= SEQUENCE
+{ heldConnection ConnectionID,
+ holdingDevice SubjectDeviceID,
+ localConnectionInfo LocalConnectionState OPTIONAL,
+ cause EventCause,
+ extensions CSTACommonArguments OPTIONAL
+}
+NetworkReachedEvent ::= SEQUENCE
+{ outboundConnection ConnectionID,
+ networkInterfaceUsed SubjectDeviceID,
+ callingDevice CallingDeviceID,
+ calledDevice CalledDeviceID,
+ lastRedirectionDevice RedirectionDeviceID,
+ localConnectionInfo LocalConnectionState OPTIONAL,
+ cause EventCause
+-- networkCallingDevice NetworkCallingDeviceID OPTIONAL,
+-- networkCalledDevice NetworkCalledDeviceID OPTIONAL,
+-- associatedCallingDevice AssociatedCallingDeviceID OPTIONAL
+-- extensions CSTACommonArguments OPTIONAL
+}
+OriginatedEvent ::= SEQUENCE
+{ originatedConnection ConnectionID,
+ callingDevice SubjectDeviceID,
+ calledDevice CalledDeviceID,
+ localConnectionInfo LocalConnectionState OPTIONAL,
+ cause EventCause,
+ networkCallingDevice NetworkCallingDeviceID OPTIONAL,
+ networkCalledDevice NetworkCalledDeviceID OPTIONAL,
+ associatedCallingDevice AssociatedCallingDeviceID OPTIONAL,
+ associatedCalledDevice AssociatedCalledDeviceID OPTIONAL,
+ extensions CSTACommonArguments OPTIONAL
+}
+QueuedEvent ::= SEQUENCE
+{ queuedConnection ConnectionID,
+ queue SubjectDeviceID,
+ callingDevice CallingDeviceID,
+ calledDevice CalledDeviceID,
+ lastRedirectionDevice RedirectionDeviceID,
+ callsInFront [1] IMPLICIT INTEGER OPTIONAL,
+ localConnectionInfo LocalConnectionState OPTIONAL,
+ cause EventCause,
+ networkCallingDevice NetworkCallingDeviceID OPTIONAL,
+ networkCalledDevice NetworkCalledDeviceID OPTIONAL,
+ associatedCallingDevice AssociatedCallingDeviceID OPTIONAL,
+ associatedCalledDevice AssociatedCalledDeviceID OPTIONAL
+}
+RetrievedEvent ::= SEQUENCE
+{ retrievedConnection ConnectionID,
+ retrievingDevice SubjectDeviceID,
+ localConnectionInfo LocalConnectionState OPTIONAL,
+ cause EventCause
+}
+ServiceInitiatedEvent ::= SEQUENCE
+{ initiatedConnection ConnectionID,
+ initiatingDevice SubjectDeviceID,
+ localConnectionInfo LocalConnectionState OPTIONAL,
+ cause EventCause,
+ networkCallingDevice NetworkCallingDeviceID OPTIONAL,
+ networkCalledDevice NetworkCalledDeviceID OPTIONAL,
+-- associatedCallingDevice AssociatedCallingDeviceID OPTIONAL
+ extensions CSTACommonArguments OPTIONAL
+}
+TransferredEvent ::= SEQUENCE
+{ primaryOldCall ConnectionID,
+ secondaryOldCall [0] IMPLICIT ConnectionID OPTIONAL,
+ transferringDevice SubjectDeviceID,
+ transferredToDevice SubjectDeviceID,
+ transferredConnections [1] IMPLICIT ConnectionList,
+ localConnectionInfo LocalConnectionState OPTIONAL,
+ cause EventCause
+-- extensions CSTACommonArguments OPTIONAL
+}
+PhysicalDeviceFeatureEvents ::= CHOICE
+{
+-- buttonInformation [ 0] IMPLICIT ButtonInformationEvent,
+ buttonPress [ 1] IMPLICIT ButtonPressEvent,
+-- displayUpdated [ 2] IMPLICIT DisplayUpdatedEvent,
+-- hookswitch [ 3] IMPLICIT HookswitchEvent,
+-- lampMode [ 4] IMPLICIT LampModeEvent,
+-- messageWaiting [ 5] IMPLICIT MessageWaitingEvent,
+-- microphoneGain [ 6] IMPLICIT MicrophoneGainEvent,
+-- microphoneMute [ 7] IMPLICIT MicrophoneMuteEvent,
+ ringerStatus [ 8] IMPLICIT RingerStatusEvent
+-- speakerMute [ 9] IMPLICIT SpeakerMuteEvent,
+-- speakerVolume [10] IMPLICIT SpeakerVolumeEvent
+}
+ButtonPressEvent ::= SEQUENCE
+{ device SubjectDeviceID,
+ button ButtonID,
+ buttonLabel IA5String OPTIONAL,
+ buttonAssociatedNumber DeviceID OPTIONAL,
+ extensions CSTACommonArguments OPTIONAL }
+
+ButtonID ::= OCTET STRING
+
+RingerStatusEvent ::= SEQUENCE
+{ device SubjectDeviceID,
+ ringer RingerID,
+ ringMode RingMode OPTIONAL,
+ extensions CSTACommonArguments OPTIONAL
+}
+
+RingerID ::= OCTET STRING
+
+RingMode ::= ENUMERATED
+{ ringing (0),
+ notRinging (1)
+}
+
+LogicalDeviceFeatureEvents ::= CHOICE
+{ agentBusy [ 0] IMPLICIT AgentBusyEvent,
+-- agentLoggedOn [ 1] IMPLICIT AgentLoggedOnEvent,
+-- agentLoggedOff [ 2] IMPLICIT AgentLoggedOffEvent,
+-- agentNotReady [ 3] IMPLICIT AgentNotReadyEvent,
+ agentReady [ 4] IMPLICIT AgentReadyEvent
+-- agentWorkingAfterCall [ 5] IMPLICIT AgentWorkingAfterCallEvent,
+-- autoAnswer [ 6] IMPLICIT AutoAnswerEvent,
+-- autoWorkMode [ 7] IMPLICIT AutoWorkModeEvent,
+-- callBack [ 8] IMPLICIT CallBackEvent,
+-- callBackMessage [ 9] IMPLICIT CallBackMessageEvent,
+-- callerIDStatus [10] IMPLICIT CallerIDStatusEvent,
+-- doNotDisturb [11] IMPLICIT DoNotDisturbEvent,
+-- forwarding [12] IMPLICIT ForwardingEvent,
+-- presenceState [14] IMPLICIT PresenceStateEvent,
+-- routeingMode [13] IMPLICIT RouteingModeEvent
+}
+AgentBusyEvent ::= SEQUENCE
+{ agentDevice SubjectDeviceID
+}
+
+AgentReadyEvent ::= SEQUENCE
+{ agentDevice SubjectDeviceID
+}
+VendorSpecEvents::= CHOICE
+{ privateEvent [ 0] IMPLICIT PrivateEvent}
+
+PrivateEvent ::= SEQUENCE
+{-- security CSTASecurityData OPTIONAL,
+privateData CSTAPrivateData }
+
+ConnectionID ::= [APPLICATION 11] CHOICE
+{
+ deviceID [1] LocalDeviceID,
+ both SEQUENCE
+ { callID [0] IMPLICIT CallID,
+ deviceID [1] LocalDeviceID
+ }
+}
+
+CallID ::= OCTET STRING
+
+LocalDeviceID ::= CHOICE
+{ staticID DeviceID
+}
+
+ConnectionList ::= SEQUENCE OF SEQUENCE
+ { newConnection [0] EXPLICIT ConnectionID OPTIONAL, --! добавлен EXPLICIT
+ associatedNID [3] associatedNID_ OPTIONAL --! CHOICE вынесен отдельно
+ }
+associatedNID_ ::= CHOICE
+ { deviceID DeviceID
+ }
+
+LocalConnectionState ::= [APPLICATION 14] IMPLICIT ENUMERATED
+{ null (0),
+ initiated (1),
+ alerting (2),
+ connected (3),
+ hold (4),
+ queued (5),
+ fail (6)
+}
+
+CallingDeviceID ::= [APPLICATION 1] CHOICE
+ {deviceIdentifier DeviceID,
+ notKnown [7] IMPLICIT NULL}
+
+CalledDeviceID ::= [APPLICATION 2] CHOICE
+ {deviceIdentifier DeviceID,
+ notKnown [7] IMPLICIT NULL}
+
+SubjectDeviceID ::= [APPLICATION 3] CHOICE
+ {deviceIdentifier DeviceID,
+ notKnown [7] IMPLICIT NULL}
+
+RedirectionDeviceID ::= [APPLICATION 4] CHOICE
+ {numberdialed DeviceID,
+ notKnown [7] IMPLICIT NULL,
+ notRequired [8] IMPLICIT NULL,
+ notSpecified [9] IMPLICIT NULL}
+
+AssociatedCallingDeviceID ::= [APPLICATION 5] CHOICE
+ {deviceIdentifier DeviceID,
+ notKnown [7] IMPLICIT NULL}
+
+AssociatedCalledDeviceID ::= [APPLICATION 6] CHOICE
+ {deviceIdentifier DeviceID,
+ notKnown [7] IMPLICIT NULL}
+
+NetworkCallingDeviceID ::= [APPLICATION 7] CHOICE
+ {deviceIdentifier DeviceID,
+ notKnown [7] IMPLICIT NULL}
+
+NetworkCalledDeviceID ::= [APPLICATION 8] CHOICE
+ {deviceIdentifier DeviceID,
+ notKnown [7] IMPLICIT NULL}
+
+DeviceID ::= SEQUENCE
+{ deviceIdentifier CHOICE
+ { dialingNumber [0] IMPLICIT NumberDigits,
+ deviceNumber [1] IMPLICIT DeviceNumber,
+ other [6] IMPLICIT OtherPlan
+ }
+}
+OtherPlan ::= OCTET STRING -- Allows future expansion to cover other numbering plans
+
+NumberDigits ::= IA5String
+
+DeviceNumber ::= INTEGER
+
+MonitorCrossRefID ::= [APPLICATION 21] INTEGER
+
+CSTACommonArguments ::= [APPLICATION 30] IMPLICIT SEQUENCE
+{ privateData [1] IMPLICIT SEQUENCE OF CSTAPrivateData OPTIONAL }
+
+CSTAPrivateData ::= CHOICE
+{ string OCTET STRING,
+ private KmeSpecificPrivateData
+} -- The actual encoding is added here,
+
+KmeSpecificPrivateData ::= CHOICE
+{
+-- kmeCallControl [1] KmeCallControlSrvEvt,
+-- kmeDeviceStatus [2] KmeDeviceStatus,
+-- kmeDeviceMonitor [3] KmeDeviceMonitor,
+ kmeSystemData [4] KmeSystemData,
+-- kmeLocalAlerm [5] KmeLocalAlerm,
+ kmeAdditionalData [6] KmeAdditionalData,
+ kmePrivateEvent [7] KmePrivateEvent,
+ kmeResourceControl [8] KmeResourceControl
+-- kmeGeneric [9] KmeGenericSrvEvt,
+-- kmeExtendedDataAccess [10] OCTET STRING
+-- kmePDFControl [11] KmePDFSrvEvt, -- Ver2.0
+-- kmeAlterIf [12] KmeAlterIfSrvEvt, -- TDA600
+-- kmeHotelControl [13] KmeHotelSrvEvt -- TDA600 v4.0
+}
+KmeAdditionalData ::= CHOICE
+{
+-- fowardType [1] KmeForwardType, -- SetForwarding
+-- trunkId [2] KmeTrunkId, -- Not Used.
+-- otherDevice [3] KmeOtherDevice, -- GetSwitchingFunctionDevices
+-- vmRecExtNo [4] IA5String, -- ConsultationCall
+-- deviceCategory [5] KmeChangedDeviceCategory, -- SwitchingFunctionDevice Changed
+ device [6] EXPLICIT DeviceID, -- GetAutoWorkMode-Request, SetAutoWorkMode-Request
+-- featureNumber [7] KmeFeatureNumber, -- AnswerCall-Request, Delivered-Event
+-- proprietaryContents [8] KmeProprietaryChars, -- Set Display
+ holdType [9] EXPLICIT KmeHoldType, -- Held Event
+-- conditionCode [10] KmeCdrConditionCode, -- Call Detail Records Report
+-- lockDisplay [11] BOOLEAN, -- SetDisplay
+-- forcedAlerting [12] KmeForcedAlerting, -- DeflectCall
+ callID [13] EXPLICIT CallID, -- RingStatus
+-- ogmContinuation [14] BOOLEAN, -- DeflectCall
+-- broadcastGroupNo [15] INTEGER, -- SInit,Orig,Delivered,Established
+-- ringPattern [16] INTEGER, -- DeflectCall V2.0
+ didNo [17] EXPLICIT DeviceID -- Delivered V2.0
+-- confGroupNo [18] INTEGER -- SInit,Orig,Deliv,Estab,Trans-Evt
+}
+KmeHoldType ::= ENUMERATED
+{ consultation (0),
+ normal (1),
+ exclusive (2)
+}
+
+escape ::= CHOICE
+{ ARGUMENT EscapeArgument,
+ RESULT EscapeResult
+-- ERRORS {universalFailure}
+-- CODE local: 51
+}
+
+EscapeArgument ::= SEQUENCE
+{ --escapeRegisterID EscapeRegisterID OPTIONAL,
+ --security CSTASecurityData OPTIONAL,
+ privateData CSTAPrivateData }
+
+EscapeResult ::= CHOICE
+{ extensions CSTACommonArguments,
+ noData NULL
+}
+
+KmeSystemData ::= CHOICE
+{ getSystemData [0] KmeGetSystemData,--!
+ setSystemData [1] KmeSetSystemData,
+--systemDataChanged [2] KmeSystemDataChanged,
+ systemDataLinkedReply [3] EXPLICIT KmeSystemDataLinkedReply,
+ getSystemDataPosAck [4] EXPLICIT KmeGetSystemDataPosAck
+--lockSystemData [5] KmeLockSystemData, -- 2002/05/17
+--systemDataStatus [6] KmeSystemDataStatus, -- 2002/05/17
+--dataRevisionRecord [7] KmeSystemDataRevision, -- 2002/12/19
+--getDataRevisionRecord [8] KmeGetSystemDataRevision, -- V2.0
+--setprogrammingEventOn [9] KmeSetProgrammingEventOn -- V2.0
+}
+KmeGetSystemData ::= CHOICE
+{ request KmeGetSystemDataReq --!
+--result KmeGetSystemDataRsp
+}
+KmeGetSystemDataReq ::= CHOICE
+{ systemData [0] EXPLICIT ENUMERATED
+ {sysTimeStamp (0),
+ devTimeStamp (1), -- Not used
+ featureList (2),
+ speedDial (3), -- Not used
+ trunkGroup (4),
+ extensionGroup (5),
+ pickupGroup (6),
+ pagingGroup (7),
+ incomingGroup (8),
+ dayNightMode (9),
+ doorPhone (10),
+ vmGroup (11),
+ manufacturerName (12), -- 3rd Party
+ subdomainName (13), -- 3rd Party
+ softwareVersion (14), -- 3rd Party
+ ctiVersion (15), -- 3rd Party
+ regionCode (16), -- 3rd Party
+ systemTime (17), -- 3rd Party
+ numberOfMsgPort (18), -- 3rd Party
+ psGroup (19), -- 3rd Party
+ whoAmI (20), -- V1.1
+ broadcastGroup (21), -- V1.1
+ pbxType (22), -- V2.0
+ externalSensor (23), -- V2.0
+ svm (24), -- TDA30 V2.2
+ pdn (25)}, -- TDA600 V3.1
+ incomGMember [3] IMPLICIT SEQUENCE
+ {groupNo DeviceID },
+ deviceList [4] KmeRequestedDevice --!
+}
+KmeRequestedDevice ::= CHOICE -- for GetSystemData.deviceList
+{ --device [0] DeviceID,
+ category [1] KmeDeviceCategory} --!
+
+KmeDeviceCategory ::= CHOICE
+{ standardDevice [0] EXPLICIT DeviceCategory--!
+ -- kmeDevice [1] KmeOtherDevice
+}
+DeviceCategory ::= ENUMERATED
+{ acd (0),
+ group (1),
+ networkInterface (2), --!
+ park (3),
+ routeingDevice (4),
+ station (5), --!
+ voiceUnit (6),
+ other (7)
+}
+KmeSystemDataLinkedReply ::= SEQUENCE
+{ crossRefID [0] EXPLICIT ServiceCrossRefID, -- 01/12/17
+ segmentID [1] EXPLICIT INTEGER,
+ lastSegment [2] EXPLICIT BOOLEAN,
+ sysData [3] EXPLICIT KmeGetSystemDataRsp OPTIONAL -- 02/04/22
+}
+ServiceCrossRefID ::= OCTET STRING
+
+KmeGetSystemDataPosAck ::= ServiceCrossRefID -- Cross Reference Identifier01/12/17
+
+KmeGetSystemDataRsp ::= SEQUENCE
+{ -- Whole system data
+--timeStamp [0] KmeTimeStamp OPTIONAL, -- PCC
+--featureList [1] KmeFeatureList OPTIONAL, -- PCC
+--speedDial [2] KmeSpeedDial OPTIONAL, -- PCC
+--trunkGroup [3] KmeExtTrkGroupList OPTIONAL, -- PCC
+--extGroup [4] KmeExtTrkGroupList OPTIONAL, -- PCC
+--pickGroup [5] KmePckPagGroupList OPTIONAL, -- PCC
+--pagingGroup [6] KmePckPagGroupList OPTIONAL, -- PCC
+--incomingGroup [7] KmeIncomingGroupList OPTIONAL, -- PCC
+--dayNightMode [8] KmeDayNightMode OPTIONAL, -- PCC
+--wakeUp [9] KmeWakeUpInfo OPTIONAL, -- PCC
+--remoteLock [10] KmeDeviceLock OPTIONAL, -- PCC
+--callLogLock [11] KmeDeviceLock OPTIONAL, -- PCC
+--absentMessage [12] KmeAbsentMessage OPTIONAL, -- PCC
+--forwardDnd [13] ForwardList OPTIONAL, -- PCC
+--trkGMembers [14] KmeTrkMembers OPTIONAL, -- PCC
+--extGMembers [15] KmeExtMembers OPTIONAL, -- PCC
+--incomGMembers [16] KmeIcmGrpMembers OPTIONAL, -- PCC
+--doorPhone [17] KmeDoorPhone OPTIONAL, -- PCC
+--vmGroup [18] KmeVmGroupList OPTIONAL, -- PCC
+ manufacturerName [19] IA5String OPTIONAL, -- 3rd Party
+ subdomainName [20] IA5String OPTIONAL, -- 3rd Party
+ softwareVersion [21] IA5String OPTIONAL, -- 3rd Party
+ ctiVersion [22] IA5String OPTIONAL, -- 3rd Party
+ regionCode [23] IA5String OPTIONAL, -- 3rd Party
+ systemTime [24] GeneralizedTime OPTIONAL, -- 3rd Party
+ numberOfMsgPort [25] EXPLICIT NumberOfMsgPort OPTIONAL, -- 3rd Party
+--psGroup [26] KmePsGroupList OPTIONAL, -- 3rd Party
+--youAre [27] DeviceID OPTIONAL, -- V1.1
+--svm [28] KmeSvmList OPTIONAL, -- TDA30 V2.2
+--pdn [29] KmePdnGMembers OPTIONAL, -- TDA600 V3.1
+-- Each device data
+--cos [34] INTEGER OPTIONAL, -- 3rd Party
+--phoneProperty [35] KmePhoneProperty OPTIONAL, -- 3rd Party
+--assocIncomGroup [36] KmeGroupMembers OPTIONAL, -- 3rd Party
+--messageWaiting [37] SEQUENCE OF DeviceID OPTIONAL, -- 3rd Party
+ deviceList [38] EXPLICIT KmeDeviceStateList OPTIONAL, -- 3rd Party
+--assocExtGroup [39] INTEGER OPTIONAL, -- 01/12/17
+--vmGMembers [40] KmeIcmGrpMembers OPTIONAL, -- 02/05/20
+--extName [41] KmeExtName OPTIONAL, -- V1.1
+--broadcastGroup [42] KmeBroadcastGroupList OPTIONAL, -- V1.1
+--broadcastGMembers [43] KmeBroadcastGrpMembers OPTIONAL, -- V1.1
+--fcoKeyList [44] KmeFcoKeyList OPTIONAL, -- V2.0
+--sxdpMaster [45] DeviceID OPTIONAL, -- V2.0
+ pbxType [46] INTEGER OPTIONAL -- V2.0
+--externalSensor [47] KmeExternalSensorList OPTIONAL, -- V2.0
+--deviceDataList [48] KmeDeviceDataList OPTIONAL, -- TDA600
+--guestCheckStatus [49] KmeCheckStatusList OPTIONAL -- TDA600 V4.0
+}
+NumberOfMsgPort ::= SEQUENCE
+{ numberOfMsgPort INTEGER,
+ numberOfFreePort INTEGER}
+
+KmeDeviceStateList ::= SEQUENCE OF KmeDeviceStateEntry
+
+KmeDeviceStateEntry ::= SEQUENCE
+{ device DeviceID,
+ number IA5String OPTIONAL, -- Ext No, CO No, Park Area No.
+ status KmeDeviceState
+}
+KmeDeviceState ::= ENUMERATED
+{ ins (0),
+ ous (1)
+}
+KmePrivateEvent ::= CHOICE
+{--digitsReport [1] KmeDigitsReport,
+ ogmStatus [2] EXPLICIT KmeOgmStatus,
+-- wakeupResult [3] KmeWakeupResult,
+-- unconferenced [4] KmeUnconferenced,
+-- tamEnded [5] KmeTamEnded, -- 2002/04/26 05/17 mod.
+-- pcRecEnded [6] KmePcRecEnded, -- 2002/05/17 Added.
+-- callbackNotification [7] CallBackNotification, -- 2002/05/28 Added
+ freeOgmPort [8] KmeFreeOgmPort -- 2002/08/26 Added
+-- pDFStatus [9] KmePDFStatus -- Ver2.0
+}
+KmeOgmStatus ::= SEQUENCE
+{ connection ConnectionID,
+ state KmeOgmPlayState,
+ ogmId INTEGER,
+ ogmPortNumber DeviceID}
+
+KmeOgmPlayState ::= ENUMERATED
+{ started (0),
+ ended (1)}
+
+KmeFreeOgmPort ::= INTEGER
+
+KmeSetSystemData ::= CHOICE
+{acdQueue [3] EXPLICIT SEQUENCE
+ {device DeviceID,
+ attribute CHOICE
+ {acdMode BOOLEAN,
+ ctiWaitTime INTEGER}
+ }
+}
+KmeResourceControl ::= CHOICE
+ { ogmStart [0] EXPLICIT KmeOgmStart,
+ ogmStop [1] EXPLICIT KmeOgmStop}
+
+ KmeOgmStart ::= SEQUENCE
+{ connection ConnectionID,
+ ogmId INTEGER}
+
+KmeOgmStop ::= ConnectionID
+
+EventCause ::= ENUMERATED
+-- a general list of cause codes
+-- Present in Added in Added in
+-- Version 1 Version 2 Version 3
+{ aCDBusy (57),
+ aCDForward (58),
+ aCDSaturated (59),
+ activeParticipation (1),
+ alertTimeExpired (60),
+ alternate (2),
+ autoWork (61),
+ blocked (35),
+ busy (3),
+ callBack (4),
+ callCancelled (5),
+ callForward (9),
+ callForwardImmediate (6),
+ callForwardBusy (7),
+ callForwardNoAnswer (8),
+ callNotAnswered (10),
+ callPickup (11),
+ campOn (12),
+ campOnTrunks (62),
+ characterCountReached (36),
+ conference (63),
+ consultation (37),
+ destDetected (64),
+ destNotObtainable (13),
+ destOutOfOrder (65),
+ distributed (38),
+ distributionDelay (66),
+ doNotDisturb (14),
+ dTMFDigitDetected (39),
+ durationExceeded (40),
+ endOfMessageDetected (41),
+ enteringDistribution (42),
+ forcedPause (43),
+ forcedTransition (67),
+ incompatibleDestination (15),
+ intrude (68),
+ invalidAccountCode (16),
+ invalidNumberFormat (69),
+ joinCall (70),
+ keyOperation (17),
+ keyOperationInUse (71),
+ lockout (18),
+ maintenance (19),
+ makeCall (44),
+ makePredictiveCall (72),
+ messageDurationExceeded (73),
+ messageSizeExceeded (45),
+ multipleAlerting (74),
+ multipleQueuing (75),
+ networkCongestion (20),
+ networkDialling (76),
+ networkNotObtainable (21),
+ networkOutOfOrder (77),
+ networkSignal (46),
+ newCall (22),
+ nextMessage (47),
+ noAvailableAgents (23),
+ normal (78),
+ normalClearing (48),
+ noSpeechDetected (49),
+ notAvaliableBearerService (79),
+ notSupportedBearerService (80),
+ numberChanged (50),
+ numberUnallocated (81),
+ overflow (26),
+ override (24),
+ park (25),
+ queueCleared (82),
+ recall (27),
+ redirected (28),
+ remainsInQueue (83),
+ reorderTone (29),
+ reserved (84),
+ resourcesNotAvailable (30),
+ selectedTrunkBusy (85),
+ silentParticipation (31),
+ singleStepConference (51),
+ singleStepTransfer (52),
+ speechDetected (53),
+ suspend (86),
+ switchingFunctionTerminated (54),
+ terminationCharacterReceived (55),
+ timeout (56),
+ transfer (32),
+ trunksBusy (33),
+ unauthorisedBearerService (87)}
+
+SnapshotDeviceArgument ::= SEQUENCE
+{ snapshotObject DeviceID}
+
+SnapshotDeviceResult ::= SEQUENCE
+{ crossRefIDorSnapshotData
+ CHOICE
+ { serviceCrossRefID ServiceCrossRefID,
+ snapshotData SnapshotDeviceData
+ }
+}
+ServiceCrossRefID ::= OCTET STRING
+
+SnapshotDeviceData ::= [APPLICATION 22] IMPLICIT SEQUENCE OF SnapshotDeviceResponseInfo
+
+SnapshotDeviceResponseInfo ::= SEQUENCE
+{ connectionIdentifier ConnectionID,
+ localCallState CallState}
+
+CallState ::= CHOICE
+{ compoundCallState [0] IMPLICIT CompoundCallState}
+
+CompoundCallState ::= SEQUENCE OF LocalConnectionState
+
+AnswerCallArgument ::= SEQUENCE --CODE local: 2
+{ callToBeAnswered ConnectionID}
+
+ClearConnectionArgument ::= SEQUENCE --CODE local: 5
+{ connectionToBeCleared ConnectionID}
+
+MakeCallArgument ::= SEQUENCE --CODE local: 10
+{ callingDevice DeviceID,
+ calledDirectoryNumber DeviceID
+}
+MakeCallResult ::= SEQUENCE
+{ callingDevice ConnectionID}
+
+HoldCallArgument ::= SEQUENCE --CODE local: 9
+{ callToBeHeld ConnectionID}
+
+TransferCallArgument ::= SEQUENCE --CODE local: 16
+{ heldCall ConnectionID,
+ activeCall ConnectionID}
+
+TransferCallResult ::= SEQUENCE
+{ transferredCall ConnectionID}
+
+ButtonPressArgument ::= SEQUENCE --CODE local: 260
+{ device DeviceID,
+ button ButtonID}
+
+ButtonID ::= OCTET STRING
diff --git a/_misc/main.go b/_misc/main.go
new file mode 100644
index 0000000..139b7a2
--- /dev/null
+++ b/_misc/main.go
@@ -0,0 +1,251 @@
+package main
+
+import (
+ "encoding/hex"
+ "flag"
+ "fmt"
+
+ "dim13.org/asn1/ber"
+ "dim13.org/asn1/spdu"
+)
+
+/* Limits
+ *
+ * Parameter Maximum Value
+ *
+ * PDU length including header 240
+ * InvokeID 32767
+ * (ROSE)
+ * DeviceID 32
+ * (MakeCall, DialDigits, ConsulationCall)
+ * DeviceID from TDA/TDE 16
+ * (In events)
+ * charactersToSend 64
+ * (GenerateDigits)
+ */
+
+var service = flag.String("service", "192.168.240.20:33333", "PBX CTI Service")
+var conn spdu.Conn
+
+func init() {
+ flag.Parse()
+}
+
+/* A-ASSOCIATE Request
+ *
+ * 60 23 AARQ-apdu
+ * 80 02 07 80 protocol-version { version1 }
+ * A1 07 application-context-name
+ * 06 05 2B 0C 00 81 5A { 1 3 12 0 218 }
+ * BE 14 user-information
+ * 28 12
+ * 06 07 2B 0C 00 82 1D 81 48 direct-reference { 1 3 12 0 285 200 }
+ * A0 07 single-ASN1-type
+ * (ACSEUserInfomrationForCSTA)
+ * A0 05 newDefinition
+ * 03 03 00 08 00 cSTAVersion { versionFive }
+ */
+
+var associate = []byte{
+ 0x60, 0x23,
+ 0x80, 0x02, 0x07, 0x80,
+ 0xA1, 0x07,
+ 0x06, 0x05, 0x2B, 0x0C, 0x00, 0x81, 0x5A,
+ 0xBE, 0x14,
+ 0x28, 0x12,
+ 0x06, 0x07, 0x2B, 0x0C, 0x00, 0x82, 0x1D, 0x81, 0x48,
+ 0xA0, 0x07,
+ 0xA0, 0x05,
+ 0x03, 0x03, 0x00, 0x08, 0x00,
+}
+
+/* A-ACCOCIATE Result
+ * 61 2F AARE-apdu
+ * 80 02 07 80 protocol-version { version1 }
+ * A1 07 application-context-name
+ * 06 05 2B 0C 00 81 5A { 1 3 12 0 218 }
+ * A2 03 result
+ * 02 01 00 accepted
+ * A3 05 result-source-diagnostic
+ * A1 03 acse-service-user
+ * 02 01 00 no-reason-given
+ * BE 14 user-information
+ * 28 12
+ * 06 07 2B 0C 00 82 1D 81 48 direct-reference { 1 3 120 285 200 }
+ * A0 07 single-ASN1-type
+ * (ACSEUserInformationForCSTA)
+ * A0 05 newDefinition
+ * 03 03 00 08 00 cSTAVersion { versionFive }
+ */
+
+/* A-REJECT
+ * 61 19 AARE-apdu
+ * 80 02 07 80 protocol-version { version1 }
+ * A1 07 application-context-name
+ * 06 05 2B 0C 00 81 5A { 1 3 12 0 218 }
+ * A2 03 result
+ * 02 01 01 rejected-permanent
+ * A3 05 result-source-diagnostic
+ * A1 03 acse-service-user
+ * 02 01 01 no-reason-given
+ */
+
+/* A-RELEASE Request
+ *
+ * 62 00 RLRQ-apdu
+ */
+
+var release = []byte{0x62, 0x00}
+
+/* A-RELEASE Result
+ *
+ * 63 00 RLRE-apdu
+ */
+
+/* SystemStatus Request
+ * A1 0C ROSE-Invoke
+ * 02 01 01 invokeId present: 1
+ * 02 02 00 D3 opcode local: 211
+ * 30 03 SystemStatusArg
+ * 0A 01 02 systemStatus normal
+ */
+
+/* SystemStatus Result
+ * A2 0B ROSE-ReturnResult
+ * 02 01 01 invokeId present: 1
+ * 30 06 SystemStatusRes
+ * 02 02 00 D3 opcode local: 211
+ * 05 00 noData
+ */
+
+var status = []byte{
+ 0xA2, 0x0B,
+ 0x02, 0x01, 0x01,
+ 0x30, 0x06,
+ 0x02, 0x02, 0x00, 0xD3,
+ 0x05, 0x00,
+}
+
+/* A-ABORT
+ * 64 03 ABRT-apdu
+ * 80 01 00 ABRT-source: acse-service-user
+ */
+
+/* Request CO lines
+ * A1 16 ROSE-Invoke
+ * 02 02 00 E0 invokeId: 224
+ * 02 01 33 opcode local: 51
+ * 30 0D EscapeArgument
+ * A4 0B kmeSystemData
+ * A0 09 getSystemData
+ * A4 07 deviceList
+ * A1 05 category
+ * A0 03 standardDevice
+ * 0A 01 02 networkInterface
+ */
+
+/* Request CO lines response
+ * A2 17 ROSE-ResultReturn
+ * 02 02 00 E0 invokeId: 224
+ * 30 11 result
+ * 02 01 33 opcode local: 51
+ * 7E 0C
+ * A1 0A
+ * A4 08
+ * A4 06
+ * 04 04 30 41 31 36 OCTET STRING: '0A16'
+ */
+
+var coLines = []byte{
+ 0xA1, 0x16,
+ 0x02, 0x02, 0x00, 0xE0,
+ 0x02, 0x01, 0x33,
+ 0x30, 0x0D,
+ 0xA4, 0x0B,
+ 0xA0, 0x09,
+ 0xA4, 0x07,
+ 0xA1, 0x05,
+ 0xA0, 0x03,
+ 0x0A, 0x01, 0x02,
+}
+
+/* Request EXT
+ * A1 16 ROSE-Invoke
+ * 02 02 06 02 invokeId: 1538
+ * 02 01 33 opcode local: 51
+ * 30 0D EscapeArgument
+ * A4 0B kmeSystemData
+ * A0 09 getSystemData
+ * A4 07 deviceList
+ * A1 05 category
+ * A0 03 standardDevice
+ * 0A 01 05 station
+ */
+
+var ext = []byte{
+ 0xA1, 0x16,
+ 0x02, 0x02, 0x06, 0x02,
+ 0x02, 0x01, 0x33,
+ 0x30, 0x0D,
+ 0xA4, 0x0B,
+ 0xA0, 0x09,
+ 0xA4, 0x07,
+ 0xA1, 0x05,
+ 0xA0, 0x03,
+ 0x0A, 0x01, 0x05,
+}
+
+/* Monitor 111
+ * A1 11 ROSE-Invoke
+ * 02 01 78 invokeId: 120
+ * 02 01 47 opcode local: 71
+ * 30 09 MonitorStartArgument
+ * 30 05 MonitorObject (CSTAObject)
+ * 80 03 31 31 31 dialingNumber '111'
+ * A0 00 MonitorFilter?
+ */
+
+func dump(b []byte) {
+ fmt.Println(hex.Dump(b))
+ fmt.Println(ber.Dump(b))
+}
+
+func Ask(c spdu.Conn, out []byte) []byte {
+ fmt.Println("Ask")
+ dump(out)
+ c.Write(out)
+ in, _ := spdu.ReadAll(c)
+ fmt.Printf("Packet length: 0x%.2X\n", len(in))
+ dump(in)
+ return in
+}
+
+func Status(c spdu.Conn) {
+ fmt.Println("Status")
+ in, _ := spdu.ReadAll(c)
+ fmt.Printf("Packet length: 0x%.2X\n", len(in))
+ dump(in)
+ out := status
+ out[4] = in[4]
+ dump(out)
+ c.Write(out)
+}
+
+func main() {
+ conn, _ = spdu.Dial(*service)
+ defer conn.Close()
+
+ Ask(conn, associate)
+ Status(conn)
+ defer Ask(conn, release)
+
+ Ask(conn, coLines)
+ Status(conn)
+
+ //Ask(conn, ext)
+ Status(conn)
+ Status(conn)
+ Status(conn)
+ Status(conn)
+ Status(conn)
+}
diff --git a/_misc/makecall.pl b/_misc/makecall.pl
new file mode 100644
index 0000000..dff02ef
--- /dev/null
+++ b/_misc/makecall.pl
@@ -0,0 +1,358 @@
+#ver 0.03 (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;
+
+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 makeCall {
+ my $dialingNumber = shift;
+ my $pdu = $CSTAapdu->encode(
+ {
+ svcRequest => {
+ invokeID => 9,
+ serviceID => 10,
+ serviceArgs => {
+ callingDevice => {
+ deviceIdentifier => {
+ dialingNumber =>
+ $dialingNumber # номер абонента
+ }
+ },
+ calledDirectoryNumber => {
+ deviceIdentifier => {
+ dialingNumber =>
+ 178 # номер ICD автоинформатора
+ }
+ }
+ }
+ }
+ }
+ );
+ send_pdu($pdu);
+ $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->{svcResult}->{result}->{serviceResult}->{callingDevice} )
+ {
+ print $out->{svcResult}->{result}->{serviceResult}->{callingDevice}
+ ->{both}->{deviceID}->{staticID}->{deviceIdentifier}->{dialingNumber},
+ "\n";
+ }
+ elsif ( defined $out->{svcError}->{parameter} ) {
+
+ #my $error_parameter = (keys %{$out->{svcError}->{parameter}})[0];
+ #print $error_parameter,"\n";
+ if ( defined $out->{svcError}->{parameter}->{operation} ) {
+ my $OperationErrors = $out->{svcError}->{parameter}->{operation};
+ if ( $OperationErrors == 12 ) {
+ print $dialingNumber, " - invalidDeviceID\n";
+ }
+ elsif ( $OperationErrors == 6 ) {
+ print $dialingNumber, " - invalidCalledDeviceID\n";
+ }
+ elsif ( $OperationErrors == 31 ) {
+ print $dialingNumber, " - invalidParameterValue\n";
+ }
+ elsif ( $OperationErrors == 2 ) {
+ print $dialingNumber, " - requestIncompatibleWithObject\n";
+ }
+ else {
+ print "OperationErrors:", $OperationErrors, "\n";
+ }
+ }
+ elsif ( defined $out->{svcError}->{parameter}->{stateIncompatibility} )
+ {
+ my $StateIncompatibilityErrors =
+ $out->{svcError}->{parameter}->{stateIncompatibility};
+ if ( $StateIncompatibilityErrors == 2 ) {
+ print $dialingNumber, " - invalidObjectState\n";
+ }
+ else {
+ print "StateIncompatibilityErrors:",
+ $StateIncompatibilityErrors;
+ }
+ }
+ elsif (
+ defined $out->{svcError}->{parameter}
+ ->{systemResourceAvailability} )
+ {
+ my $SystemResourceAvailabilityErrors =
+ $out->{svcError}->{parameter}->{systemResourceAvailability};
+ if ( $SystemResourceAvailabilityErrors == 15 ) {
+ print $dialingNumber, " - deviceOutOfService\n";
+ }
+ else {
+ print "SystemResourceAvailabilityErrors:",
+ $SystemResourceAvailabilityErrors;
+ }
+ }
+ else {
+ print Dumper($out);
+ }
+ }
+ else {
+ print Dumper($out);
+ }
+}
+
+# parse ASN.1 desciptions
+my $asn = Convert::ASN1->new;
+
+#$asn->configure(tagdefault=>'EXPLICIT');
+$asn->prepare(<<ASN1) or die "prepare: ", $asn->error;
+CSTAapdu ::= CHOICE {
+ svcRequest ROIVapdu,
+ svcResult RORSapdu,
+ svcError ROERapdu
+-- svcReject RORJapdu
+}
+ROIVapdu ::= [1] IMPLICIT SEQUENCE {
+ invokeID INTEGER,
+ serviceID INTEGER,
+ serviceArgs ANY DEFINED BY serviceID
+}
+RORSapdu ::= [2] IMPLICIT SEQUENCE {
+ invokeID INTEGER,
+ result SEQUENCE {
+ serviceID INTEGER,
+ serviceResult ANY DEFINED BY serviceID OPTIONAL
+ }
+}
+ROERapdu ::= [3] IMPLICIT SEQUENCE {
+ invokeID INTEGER,
+ code INTEGER, -- local:1
+ parameter UniversalFailure
+}
+UniversalFailure ::= CHOICE
+{ operation [0] EXPLICIT OperationErrors,
+ stateIncompatibility [2] EXPLICIT StateIncompatibilityErrors,
+ systemResourceAvailability [3] EXPLICIT SystemResourceAvailabilityErrors,
+ unspecified [7] UnspecifiedErrors
+}
+OperationErrors ::= ENUMERATED
+{
+ invalidDeviceID (12),
+ invalidCalledDeviceID (6),
+ invalidParameterValue (31),
+ requestIncompatibleWithObject (2)
+}
+StateIncompatibilityErrors ::= ENUMERATED
+{
+ invalidObjectState (2)
+}
+SystemResourceAvailabilityErrors ::= ENUMERATED
+{
+ deviceOutOfService (15)
+}
+UnspecifiedErrors ::= NULL
+
+--makeCall OPERATION ::=
+--{ ARGUMENT MakeCallArgument
+-- RESULT MakeCallResult
+-- ERRORS {universalFailure}
+-- CODE local: 10
+--}
+
+MakeCallArgument ::= SEQUENCE
+{ callingDevice DeviceID,
+ calledDirectoryNumber DeviceID
+}
+MakeCallResult ::= SEQUENCE
+{ callingDevice ConnectionID}
+
+ConnectionID ::= [APPLICATION 11] CHOICE
+{
+ deviceID [1] LocalDeviceID,
+ both SEQUENCE
+ { callID [0] IMPLICIT CallID,
+ deviceID [1] LocalDeviceID
+ }
+}
+
+CallID ::= OCTET STRING
+
+LocalDeviceID ::= CHOICE
+{ staticID DeviceID}
+
+DeviceID ::= SEQUENCE
+{ deviceIdentifier CHOICE
+ { dialingNumber [0] IMPLICIT NumberDigits,
+ deviceNumber [1] IMPLICIT DeviceNumber,
+ other [6] IMPLICIT OtherPlan
+ }
+}
+OtherPlan ::= OCTET STRING
+
+NumberDigits ::= IA5String
+
+DeviceNumber ::= INTEGER
+
+systemStatus ::= CHOICE
+{ ARGUMENT SystemStatusArg,
+ RESULT SystemStatusRes
+-- ERRORS {universalFailure}
+-- CODE local: 211
+}
+SystemStatusArg ::= SEQUENCE
+{ systemStatus SystemStatus}
+
+SystemStatusRes ::= CHOICE
+{ noData NULL}
+
+SystemStatus ::= ENUMERATED
+{ normal (2),
+ messageLost (3),
+ overloadReached (6)
+}
+ASN1
+my %serviceArgs = ( #51=> 'EscapeArgument',
+ 10 => 'MakeCallArgument',
+ 211 => 'SystemStatusArg'
+);
+foreach ( keys %serviceArgs ) {
+ $asn->registertype( 'serviceArgs', $_, $asn->find( $serviceArgs{$_} ) );
+}
+my %serviceResults = ( #51=> 'EscapeResult',
+ 10 => 'MakeCallResult',
+ 211 => 'SystemStatusRes'
+);
+foreach ( keys %serviceResults ) {
+ $asn->registertype( 'serviceResult', $_,
+ $asn->find( $serviceResults{$_} ) );
+}
+$CSTAapdu = $asn->find('CSTAapdu');
+csta_connect( { 'host' => '192.168.0.66', 'port' => 33333 } );
+print "makeCall:\n";
+my @devices = ( 106, 111, 155, 156 ); # список номеров
+my $i = 0;
+for (@devices) {
+ makeCall($_);
+ if ( $i++ % 2 ) { # 2 - количество каналов SVM
+ sleep 3 # задержка на сообщение
+ }
+}
diff --git a/_misc/monitorCallerID.pl b/_misc/monitorCallerID.pl
new file mode 100644
index 0000000..7980811
--- /dev/null
+++ b/_misc/monitorCallerID.pl
@@ -0,0 +1,174 @@
+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();
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);
+ }
+ }
+}
diff --git a/_misc/monitorTDE2.pl b/_misc/monitorTDE2.pl
new file mode 100755
index 0000000..929d243
--- /dev/null
+++ b/_misc/monitorTDE2.pl
@@ -0,0 +1,299 @@
+#!/usr/bin/perl -w
+#ver 0.01 (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;
+ $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 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('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.240.20', 'port' => 33333 } );
+GetSystemData(2);
+GetSystemData(5);
+foreach my $number (@devices) {
+ MonitorStartArgument($number);
+}
+while (1) {
+ my $pdu = receive_stuff();
+ Convert::ASN1::asn_hexdump($pdu);
+ Convert::ASN1::asn_dump($pdu);
+ my $out = $CSTAapdu->decode($pdu);
+ print Dumper($out);
+ if ( defined $out->{svcRequest} ) {
+ my $serviceID = $out->{svcRequest}->{serviceID};
+ my $invokeID = $out->{svcRequest}->{invokeID};
+ my $serviceArgs = $out->{svcRequest}->{serviceArgs};
+ if ( $serviceID == 211 ) { # if SystemStatus Request
+ SystemStatusResult($invokeID);
+ }
+ }
+}
diff --git a/_misc/snapshot.pl b/_misc/snapshot.pl
new file mode 100755
index 0000000..3cbb9d7
--- /dev/null
+++ b/_misc/snapshot.pl
@@ -0,0 +1,538 @@
+#!/usr/bin/env perl
+#ver 0.11 (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;
+my @calls;
+
+sub deviceNumber {
+ my $deviceNumber = shift;
+ if ( defined $deviceNumber->{deviceNumber} ) {
+ $deviceNumber = $deviceNumber->{deviceNumber};
+ my $deviceType = $deviceNumber & 0xFFFF0000;
+ if ( $deviceType == 0x1310000 ) {
+ $deviceType = 'CO';
+ }
+ elsif ( $deviceType == 0x1210000 ) {
+ $deviceType = 'PS';
+ }
+ elsif ( $deviceType == 0x1110000 ) {
+ $deviceType = 'EXT';
+ }
+ $deviceNumber = $deviceNumber & 0x0000FFFF;
+ return $deviceType . sprintf( "%03s", $deviceNumber );
+ }
+ elsif ( defined $deviceNumber->{dialingNumber} ) {
+ return $deviceNumber->{dialingNumber};
+ }
+}
+
+sub localConnectionInfo {
+ my $localConnectionInfo = shift;
+ if ( $localConnectionInfo == 0 ) {
+ return 'null';
+ }
+ elsif ( $localConnectionInfo == 1 ) {
+ return 'initiated';
+ }
+ elsif ( $localConnectionInfo == 2 ) {
+ return 'alerting';
+ }
+ elsif ( $localConnectionInfo == 3 ) {
+ return 'connected';
+ }
+ elsif ( $localConnectionInfo == 4 ) {
+ return 'hold';
+ }
+ elsif ( $localConnectionInfo == 5 ) {
+ return 'queued';
+ }
+ elsif ( $localConnectionInfo == 6 ) {
+ return 'fail';
+ }
+ else { return $localConnectionInfo }
+}
+
+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 SnapshotDeviceRequest {
+ my $device = shift;
+ my $pdu = $CSTAapdu->encode(
+ {
+ svcRequest => {
+ invokeID => 9,
+ serviceID => 74,
+ serviceArgs => {
+ snapshotObject =>
+ { deviceIdentifier => { deviceNumber => $device } }
+ }
+ }
+ }
+ );
+
+ #$device = sprintf("%08X",$device);
+ #print("SnapshotDeviceRequest: $device\n");
+ #my $pdu = "A11002010202014A300830068104".$device;
+ #$pdu = pack('H*', $pdu);
+ send_pdu($pdu);
+}
+
+sub SnapshotDeviceResult {
+ my $refSnapshotDeviceResult = shift;
+ my $refsnapshotData =
+ ( $refSnapshotDeviceResult->{crossRefIDorSnapshotData}->{snapshotData} );
+ foreach my $SnapshotDeviceResponseInfo ( @{$refsnapshotData} ) {
+ my $callID =
+ $SnapshotDeviceResponseInfo->{connectionIdentifier}->{both}->{callID};
+ my $deviceID = deviceNumber(
+ $SnapshotDeviceResponseInfo->{connectionIdentifier}->{both}
+ ->{deviceID}->{staticID}->{deviceIdentifier} );
+ foreach my $LocalConnectionState (
+ @{
+ $SnapshotDeviceResponseInfo->{localCallState}
+ ->{compoundCallState}
+ }
+ )
+ {
+ my $ConnectionState = localConnectionInfo($LocalConnectionState);
+ push @calls, [ $callID, $deviceID, $ConnectionState ];
+ }
+
+ }
+}
+
+sub SystemStatusResult {
+ my $invokeID = shift;
+ my $pdu = $CSTAapdu->encode(
+ {
+ svcResult => {
+ invokeID => $invokeID,
+ result => { serviceID => 211, serviceResult => { noData => 1 } }
+ }
+ }
+ );
+ send_pdu($pdu); # send SystemStatus Result
+}
+
+# parse ASN.1 desciptions
+my $asn = Convert::ASN1->new;
+
+#$asn->configure(tagdefault=>'EXPLICIT');
+$asn->prepare(<<ASN1) or die "prepare: ", $asn->error;
+CSTAapdu ::= CHOICE {
+ svcRequest ROIVapdu,
+ svcResult RORSapdu
+-- svcError ROERapdu,
+-- svcReject RORJapdu
+}
+ROIVapdu ::= [1] IMPLICIT SEQUENCE {
+ invokeID INTEGER,
+ serviceID INTEGER,
+ serviceArgs ANY DEFINED BY serviceID
+}
+RORSapdu ::= [2] IMPLICIT SEQUENCE {
+ invokeID INTEGER,
+ result SEQUENCE {
+ serviceID INTEGER,
+ serviceResult ANY DEFINED BY serviceID OPTIONAL
+ }
+}
+EscapeArgument ::= SEQUENCE
+{ --escapeRegisterID EscapeRegisterID OPTIONAL,
+ --security CSTASecurityData OPTIONAL,
+ privateData CSTAPrivateData }
+
+CSTAPrivateData ::= CHOICE
+{ string OCTET STRING,
+ private KmeSpecificPrivateData
+}
+KmeSpecificPrivateData ::= CHOICE
+{ kmeSystemData [4] KmeSystemData
+}
+KmeSystemData ::= CHOICE
+{ getSystemData [0] KmeGetSystemData,
+ systemDataLinkedReply [3] EXPLICIT KmeSystemDataLinkedReply,
+ getSystemDataPosAck [4] EXPLICIT KmeGetSystemDataPosAck
+}
+KmeGetSystemData ::= CHOICE
+{ request KmeGetSystemDataReq --!
+--result KmeGetSystemDataRsp
+}
+KmeGetSystemDataReq ::= CHOICE
+{
+deviceList [4] KmeRequestedDevice --!
+}
+KmeRequestedDevice ::= CHOICE -- for GetSystemData.deviceList
+{ --device [0] DeviceID,
+ category [1] KmeDeviceCategory} --!
+
+KmeDeviceCategory ::= CHOICE
+{ standardDevice [0] EXPLICIT DeviceCategory--!
+ -- kmeDevice [1] KmeOtherDevice
+}
+DeviceCategory ::= ENUMERATED
+{ acd (0),
+ group (1),
+ networkInterface (2), --!
+ park (3),
+ routeingDevice (4),
+ station (5), --!
+ voiceUnit (6),
+ other (7)
+}
+KmeSystemDataLinkedReply ::= SEQUENCE
+{ crossRefID [0] EXPLICIT ServiceCrossRefID,
+ segmentID [1] EXPLICIT INTEGER,
+ lastSegment [2] EXPLICIT BOOLEAN,
+ sysData [3] EXPLICIT KmeGetSystemDataRsp OPTIONAL
+}
+ServiceCrossRefID ::= OCTET STRING
+
+KmeGetSystemDataPosAck ::= ServiceCrossRefID
+
+KmeGetSystemDataRsp ::= SEQUENCE
+{ deviceList [38] EXPLICIT KmeDeviceStateList OPTIONAL
+}
+KmeDeviceStateList ::= SEQUENCE OF KmeDeviceStateEntry
+
+KmeDeviceStateEntry ::= SEQUENCE
+{ device DeviceID,
+ number IA5String OPTIONAL, -- Ext No, CO No, Park Area No.
+ status KmeDeviceState
+}
+KmeDeviceState ::= ENUMERATED
+{ ins (0),
+ ous (1)
+}
+EscapeResult ::= CHOICE
+{ extensions CSTACommonArguments,
+ noData NULL
+}
+CSTACommonArguments ::= [APPLICATION 30] IMPLICIT SEQUENCE
+{ privateData [1] IMPLICIT SEQUENCE OF CSTAPrivateData OPTIONAL }
+
+CSTAPrivateData ::= CHOICE
+{ string OCTET STRING,
+ private KmeSpecificPrivateData
+}
+
+--snapshotDevice OPERATION ::=
+--{ ARGUMENT SnapshotDeviceArgument,
+-- RESULT SnapshotDeviceResult
+-- ERRORS {universalFailure}
+-- CODE local: 74}
+
+SnapshotDeviceArgument ::= SEQUENCE
+{ snapshotObject DeviceID}
+
+SnapshotDeviceResult ::= SEQUENCE
+{ crossRefIDorSnapshotData
+ CHOICE
+ { serviceCrossRefID ServiceCrossRefID,
+ snapshotData SnapshotDeviceData
+ }
+}
+
+ServiceCrossRefID ::= OCTET STRING
+
+SnapshotDeviceData ::= [APPLICATION 22] IMPLICIT SEQUENCE OF SnapshotDeviceResponseInfo
+
+SnapshotDeviceResponseInfo ::= SEQUENCE
+{ connectionIdentifier ConnectionID,
+ localCallState CallState}
+
+ConnectionID ::= [APPLICATION 11] CHOICE
+{
+ deviceID [1] LocalDeviceID,
+ both SEQUENCE
+ { callID [0] IMPLICIT CallID,
+ deviceID [1] LocalDeviceID
+ }
+}
+
+CallID ::= OCTET STRING
+
+LocalDeviceID ::= CHOICE
+{ staticID DeviceID}
+
+DeviceID ::= SEQUENCE
+{ deviceIdentifier CHOICE
+ { dialingNumber [0] IMPLICIT NumberDigits,
+ deviceNumber [1] IMPLICIT DeviceNumber,
+ other [6] IMPLICIT OtherPlan
+ }
+}
+OtherPlan ::= OCTET STRING
+
+NumberDigits ::= IA5String
+
+DeviceNumber ::= INTEGER
+
+CallState ::= CHOICE
+{ compoundCallState [0] IMPLICIT CompoundCallState}
+
+CompoundCallState ::= SEQUENCE OF LocalConnectionState
+
+LocalConnectionState ::= [APPLICATION 14] IMPLICIT ENUMERATED
+{ null (0),
+ initiated (1),
+ alerting (2),
+ connected (3),
+ hold (4),
+ queued (5),
+ fail (6)
+}
+systemStatus ::= CHOICE
+{ ARGUMENT SystemStatusArg,
+ RESULT SystemStatusRes
+-- ERRORS {universalFailure}
+-- CODE local: 211
+}
+SystemStatusArg ::= SEQUENCE
+{ systemStatus SystemStatus}
+
+SystemStatusRes ::= CHOICE
+{ noData NULL}
+
+SystemStatus ::= ENUMERATED
+{ normal (2),
+ messageLost (3),
+ overloadReached (6)
+}
+ASN1
+my %serviceArgs = (
+ 51 => 'EscapeArgument',
+ 74 => 'SnapshotDeviceArgument',
+ 211 => 'SystemStatusArg'
+);
+foreach ( keys %serviceArgs ) {
+ $asn->registertype( 'serviceArgs', $_, $asn->find( $serviceArgs{$_} ) );
+}
+my %serviceResults = (
+ 51 => 'EscapeResult',
+ 74 => 'SnapshotDeviceResult',
+ 211 => 'SystemStatusRes'
+);
+foreach ( keys %serviceResults ) {
+ $asn->registertype( 'serviceResult', $_,
+ $asn->find( $serviceResults{$_} ) );
+}
+$CSTAapdu = $asn->find('CSTAapdu');
+csta_connect( { 'host' => '192.168.240.20', 'port' => 33333 } );
+GetSystemData(2);
+GetSystemData(5);
+my $maxCO = 0;
+while (1) {
+ foreach my $number (@devices) {
+ SnapshotDeviceRequest($number);
+ }
+ undef @calls;
+ my $alldevices = $#devices + 1;
+ while ($alldevices) {
+ my $pdu = receive_stuff();
+ my $out = $CSTAapdu->decode($pdu);
+ if ( defined $out->{svcRequest} ) {
+ my $serviceID = $out->{svcRequest}->{serviceID};
+ my $invokeID = $out->{svcRequest}->{invokeID};
+ if ( $serviceID == 211 ) { # if SystemStatus Request
+ SystemStatusResult($invokeID);
+ }
+ }
+ elsif ( defined $out->{svcResult} ) {
+ my $serviceResult = $out->{svcResult}->{result}->{serviceResult};
+ my $serviceID = $out->{svcResult}->{result}->{serviceID};
+ if ( $serviceID == 74 ) {
+ SnapshotDeviceResult($serviceResult);
+ $alldevices = $alldevices - 1;
+ }
+ }
+ }
+ my $CO = 0;
+ for (@calls) {
+ $CO++ if $_->[1] =~ /^CO/;
+ }
+ if ( $maxCO < $CO ) {
+ $maxCO = $CO;
+ print chr(7);
+ }
+ #system('CLS'); # for windows, 'clear' for linux
+ print strftime( "%H:%M:%S ", localtime ), "maxCO:", $maxCO, " CO:", $CO,
+ "\n";
+ print "callID: deviceID: CallState:\n";
+ printf( "%-8s%-10s%-10s\n", $_->[0], $_->[1], $_->[2] )
+ for sort { $a->[0] cmp $b->[0] } @calls;
+ sleep 1;
+}
diff --git a/_misc/tde.c b/_misc/tde.c
new file mode 100644
index 0000000..81beda0
--- /dev/null
+++ b/_misc/tde.c
@@ -0,0 +1,366 @@
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+
+#include <stdio.h>
+#include <string.h>
+#include <time.h>
+#include <errno.h>
+#include <malloc.h>
+
+#include <CSTAapdu.h>
+#include <CSTAServices.h>
+#include <CSTAEventReportArgument.h>
+#include <MonitorStartArgument.h>
+
+/* Определяем порт и адрес АТС. */
+#define PORTNUM 33333
+#define SERVER "192.168.0.101"
+
+int s;
+int write_out(const void *buffer, size_t size, void *app_key);
+
+typedef struct buffer_s {
+ char *buf;
+ int len;
+} buffer_t;
+
+void
+parseEventReport(char *data, int length)
+{
+ CSTAEventReportArgument_t *rep = 0; /* Type to decode */
+ asn_dec_rval_t rval; /* Decoder return value */
+ size_t size; /* Number of bytes read */
+
+ /* Decode the input buffer */
+ rval = ber_decode(0, &asn_DEF_CSTAEventReportArgument,
+ (void **) &rep, data, length);
+ if (rval.code != RC_OK)
+ fprintf(stderr, "Broken encoding at byte %ld\n",
+ (long) rval.consumed);
+
+ /* Print the decoded Rectangle type as XML */
+ xer_fprint(stdout, &asn_DEF_CSTAEventReportArgument, rep);
+
+ return 0; /* Decoding finished successfully */
+}
+
+void
+dump(unsigned char *buf, int len)
+{
+ int i, j;
+
+ for (i = 0; i < len; i += 16) {
+ for (j = 0; j < 16; j++)
+ if (i + j < len)
+ printf("%02X ", (unsigned char) buf[i + j]);
+ else
+ printf(" ");
+ for (j = 0; j < 16; j++)
+ if (i + j < len) {
+ if (buf[i + j] >= 0x20)
+ printf("%c",
+ (unsigned char) buf[i + j]);
+ else
+ printf(".");
+ }
+ printf("\n");
+ }
+}
+
+void *
+memmem(const void *haystack, size_t haystacklen,
+ const void *needle, size_t needlelen)
+{
+ register const char *pn;
+ register const char *ph;
+ const char *plast;
+ size_t n;
+
+ if (needlelen == 0) {
+ return (void *) haystack;
+ }
+
+ if (haystacklen >= needlelen) {
+ ph = (const char *) haystack;
+ pn = (const char *) needle;
+ plast = ph + (haystacklen - needlelen);
+
+ do {
+ n = 0;
+ while (ph[n] == pn[n]) {
+ if (++n == needlelen) {
+ return (void *) ph;
+ }
+ }
+ } while (++ph <= plast);
+ }
+
+ return NULL;
+}
+
+#define READ 0
+#define WRITE 1
+
+void
+timestamp(int dir)
+{
+ time_t t;
+ struct tm *l;
+
+ t = time(NULL);
+ l = localtime(&t);
+ printf("\n[%02d:%02d:%02d %02d.%02d.%4d] ", l->tm_hour, l->tm_min,
+ l->tm_sec, l->tm_mday, l->tm_mon + 1, l->tm_year + 1900);
+
+ if (dir == READ)
+ printf("---- PBX -> PC ----\n");
+ else
+ printf("---- PC -> PBX ----\n");
+}
+
+void
+pktdump(char *buf, int len)
+{
+ int i, j;
+ char id[256], *cp, type, tmp[256], *c, *orig;
+ long seq, l, origlen;
+ CSTAapdu_t *apdu = 0; /* Type to decode */
+ RORSapdu_t *rors;
+ asn_dec_rval_t rval; /* Decoder return value */
+ size_t size; /* Number of bytes read */
+ buffer_t *out;
+
+ buf += 2;
+ len -= 2;
+ timestamp(READ);
+
+ /* Decode the input buffer */
+ rval = ber_decode(0, &asn_DEF_CSTAapdu, (void **) &apdu, buf, len);
+ if (rval.code != RC_OK) {
+ fprintf(stderr, "Broken encoding at byte %ld\n",
+ (long) rval.consumed);
+ return 1;
+ }
+ switch (apdu->present) {
+ case CSTAapdu_PR_svcRequest:
+ printf("invokeID %d, serviceID %d\n",
+ apdu->choice.svcRequest.invokeID,
+ apdu->choice.svcRequest.serviceID);
+ switch (apdu->choice.svcRequest.serviceID) {
+ case 211:
+ printf("SystemStatus Request\n");
+ // send SystemStatus responce
+ rors = calloc(1, sizeof(RORSapdu_t));
+ rors->invokeID = apdu->choice.svcRequest.invokeID;
+ rors->result.serviceID =
+ apdu->choice.svcRequest.serviceID;
+
+ out = calloc(1, sizeof(buffer_t));
+ out->buf = malloc(1024);
+ der_encode(&asn_DEF_RORSapdu, rors, write_out, out);
+ timestamp(WRITE);
+ printf("invokeID %d, serviceID %d\n", rors->invokeID,
+ rors->result.serviceID);
+ printf("SystemStatus Responce\n");
+ // xer_fprint(stdout, &asn_DEF_RORSapdu, rors);
+
+ memmove(out->buf + 2, out->buf, out->len);
+ out->buf[0] = 0x00;
+ out->buf[1] = out->len;
+ out->len += 2;
+ send(s, out->buf, out->len, 0);
+ free(out->buf);
+ break;
+ case CSTAServices_cSTAeventReportSID:
+ parseEventReport(apdu->choice.svcRequest.
+ serviceArgs.buf,
+ apdu->choice.svcRequest.serviceArgs.size);
+ break;
+ default:
+ printf("Unknown svcRequest:\n");
+ dump(apdu->choice.svcRequest.serviceArgs.buf,
+ apdu->choice.svcRequest.serviceArgs.size);
+ break;
+ }
+ break;
+ case CSTAapdu_PR_svcResult:
+ case CSTAapdu_PR_svcError:
+ case CSTAapdu_PR_svcReject:
+ default:
+ xer_fprint(stdout, &asn_DEF_CSTAapdu, apdu);
+ break;
+ }
+}
+
+int
+write_out(const void *buffer, size_t size, void *app_key)
+{
+ buffer_t *dest = app_key;
+ u_char *buf = buffer;
+ int i;
+
+ for (i = 0; i < size; i++)
+ dest->buf[dest->len + i] = buf[i];
+ dest->len += size;
+ return 0;
+}
+
+int sendID = 1;
+
+void
+start_monitor(char *numer)
+{
+ ROIVapdu_t *pdu;
+ MonitorStartArgument_t *rep;
+ int i;
+ buffer_t *buf;
+
+ rep = calloc(1, sizeof(MonitorStartArgument_t));
+ rep->monitorObject.present = CSTAObject_PR_deviceObject;
+ rep->monitorObject.choice.deviceObject.deviceIdentifier.present =
+ DeviceID__deviceIdentifier_PR_dialingNumber;
+ rep->monitorObject.choice.deviceObject.deviceIdentifier.
+ choice.dialingNumber.buf = numer;
+ rep->monitorObject.choice.deviceObject.deviceIdentifier.
+ choice.dialingNumber.size = strlen(numer);
+
+ pdu = calloc(1, sizeof(ROIVapdu_t));
+ pdu->invokeID = sendID++;
+ pdu->serviceID = CSTAServices_monitorStartSID;
+ pdu->serviceArgs.buf = malloc(1024);
+
+ buf = calloc(1, sizeof(buffer_t));
+ buf->buf = pdu->serviceArgs.buf;
+ der_encode(&asn_DEF_MonitorStartArgument, rep, write_out, buf);
+ pdu->serviceArgs.size = buf->len;
+
+ buf->len = 0;
+ buf->buf = malloc(1024);
+ der_encode(&asn_DEF_ROIVapdu, pdu, write_out, buf);
+
+ timestamp(WRITE);
+ xer_fprint(stdout, &asn_DEF_MonitorStartArgument, rep);
+
+ memmove(buf->buf + 2, buf->buf, buf->len);
+ buf->buf[0] = 0x00;
+ buf->buf[1] = buf->len;
+ buf->len += 2;
+ send(s, buf->buf, buf->len, 0);
+
+ free(buf->buf);
+ free(pdu->serviceArgs.buf);
+ // read_pkt();
+}
+
+int
+read_pkt(int s, unsigned char *buf)
+{
+ int nbytes, total = 0, length;
+ while (total < 2) {
+ nbytes = recv(s, &buf[total], 2 - total, 0);
+ if (nbytes == 0)
+ return 0; // соединение закрыто удаленно
+ if (nbytes < 0)
+ return -1; // ошибка чтения из сокета
+ total += nbytes;
+ }
+ if (buf[0] != 0)
+ return -2; // испорченный пакет
+ if (buf[1] == 0)
+ return 2; // прочли 2 байта - пустой пакет
+ length = ((unsigned char *) buf)[1] + 2;
+ while (total < length) {
+ nbytes = recv(s, &buf[total], length - total, 0);
+ if (nbytes == 0)
+ return 0; // соединение закрыто удаленно
+ if (nbytes < 0)
+ return -1; // ошибка чтения из сокета
+ total += nbytes;
+ }
+ return total;
+}
+
+main(argc, argv)
+ int argc;
+ char *argv[];
+{
+ int nbytes;
+ int pid;
+ int nport;
+
+ /* Начало программы. */
+ struct sockaddr_in serv_addr;
+ unsigned char buf[242] =
+ { 0x00, 0x25, 0x60, 0x23, 0x80, 0x02, 0x07, 0x80, 0xA1, 0x07, 0x06,
+ 0x05, 0x2B, 0x0C, 0x00, 0x81, 0x5A, 0xBE, 0x14, 0x28, 0x12,
+ 0x06, 0x07, 0x2B, 0x0C, 0x00, 0x82, 0x1D, 0x81, 0x48, 0xA0,
+ 0x07, 0xA0, 0x05, 0x03, 0x03, 0x00, 0x08, 0x00
+ };
+ int addrlen;
+ unsigned long addr;
+
+ nport = htons((u_short) PORTNUM);
+
+ if ((s = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
+ perror("Error calling socket()");
+ return 1;
+ }
+
+ /* В serv_addr заносим адрес и порт АТС. */
+ bzero(&serv_addr, sizeof(serv_addr));
+ serv_addr.sin_family = AF_INET;
+ serv_addr.sin_addr.s_addr = inet_addr(SERVER);
+ serv_addr.sin_port = nport;
+
+ if (connect(s, (struct sockaddr *) &serv_addr,
+ sizeof(serv_addr)) == -1) {
+ perror("Error calling connect()");
+ return 1;
+ }
+ // посылаем #A-ASSOCIATE Request
+ // dump(buf, 39);
+ send(s, buf, 39, 0);
+
+ // Получаем ответ от АТС.
+ nbytes = recv(s, buf, sizeof(buf), 0);
+ // printf("%d", nbytes)
+ dump(buf, nbytes);
+
+ if (nbytes < 0) {
+ perror("Error calling recv()");
+ return 1;
+ }
+ // проверяем на rejected-permanent
+ const unsigned char seek[] = { 0xA2, 0x03, 0x02, 0x01, 0x01 };
+ unsigned char *off_ptr = memmem(buf, sizeof(buf), seek, sizeof(seek));
+ if (off_ptr) {
+ printf("rejected-permanent\n");
+ close(s);
+ return 0;
+ }
+ // шлём #StartMonitor
+ start_monitor("101");
+ start_monitor("102");
+ start_monitor("111");
+ start_monitor("112");
+ start_monitor("113");
+ start_monitor("114");
+ start_monitor("115");
+
+ while (1) { //цикл
+ nbytes = read_pkt(s, buf);
+ if (nbytes < 0) {
+ perror("Error calling recv()");
+ return 1;
+ } else if (nbytes == 0) {
+ printf("socket closed\n");
+ return 1;
+ }
+ // dump(buf, nbytes);
+ pktdump(buf, nbytes);
+ }
+ close(s);
+ return 0;
+}