ok, it's kludgy and non-perlish but here it goes:
#
# ECHI R11 (standard).
#
$ECHI_R11_LEN = 323;
@ECHI_R11_FMT = (
['CALLID', 'V', 0, 4], ['ACWTIME', 'V', 4, 4],
['ANSHOLDTIME', 'V', 8, 4], ['CONSULTTIME', 'V', 12, 4],
['DISPTIME', 'V', 16, 4], ['DURATION', 'V', 20, 4],
['SEGSTART', 'D', 24, 4], ['SEGSTOP', 'D', 28, 4],
['TALKTIME', 'V', 32, 4], ['NETINTIME', 'V', 36, 4],
['ORIGHOLDTIME', 'V', 40, 4], ['DISPIVECTOR', 'v', 44, 2],
['DISPSPLIT', 'v', 46, 2], ['FIRSTVECTOR', 'v', 48, 2],
['SPLIT1', 'v', 50, 2], ['SPLIT2', 'v', 52, 2],
['SPLIT3', 'v', 54, 2], ['TKGRP', 'v', 56, 2],
['EQ_LOCID', 'v', 58, 2], ['ORIG_LOCID', 'v', 60, 2],
['ANS_LOCID', 'v', 62, 2], ['OBS_LOCID', 'v', 64, 2],
['ASSIST', 'b', 66, 1, 0], ['AUDIO', 'b', 66, 1, 1],
['CONFERENCE', 'b', 66, 1, 2], ['DA_QUEUED', 'b', 66, 1, 3],
['HOLDABN', 'b', 66, 1, 4], ['MALICIOUS', 'b', 66, 1, 5],
['OBSERVINGCALL', 'b', 66, 1, 6], ['TRANSFERRED', 'b', 66, 1, 7],
['AGT_RELEASED', 'b', 67, 1, 0], ['ACD', 'V', 68, 1],
['DISPOSITION', 'V', 69, 1], ['DISPPRIORITY', 'V', 70, 1],
['HELD', 'V', 71, 1], ['SEGMENT', 'V', 72, 1],
['ANSREASON', 'V', 73, 1], ['ORIGREASON', 'V', 74, 1],
['DISPSKLEVEL', 'V', 75, 1], ['EVENT1', 'V', 76, 1],
['EVENT2', 'V', 77, 1], ['EVENT3', 'V', 78, 1],
['EVENT4', 'V', 79, 1], ['EVENT5', 'V', 80, 1],
['EVENT6', 'V', 81, 1], ['EVENT7', 'V', 82, 1],
['EVENT8', 'V', 83, 1], ['EVENT9', 'V', 84, 1],
['UCID', 'Z', 85, 21], ['DISPVDN', 'Z', 106, 8],
['EQLOC', 'Z', 114, 10], ['FIRSTVDN', 'Z', 124, 8],
['ORIGLOGIN', 'Z', 132, 10], ['ANSLOGIN', 'Z', 142, 10],
['LASTOBSERVER', 'Z', 152, 10], ['DIALED_NUM', 'Z', 162, 25],
['CALLING_PTY', 'Z', 187, 13], ['LASTDIGITS', 'Z', 200, 17],
['LASTCWC', 'Z', 217, 17], ['CALLING_II', 'Z', 234, 3],
['CWC1', 'Z', 237, 17], ['CWC2', 'Z', 254, 17],
['CWC3', 'Z', 271, 17], ['CWC4', 'Z', 288, 17],
['CWC5', 'Z', 305, 17]
);
#
# ECHI R12 (expanded).
#
$ECHI_R12_LEN = 493;
@ECHI_R12_FMT = (
['CALLID', 'V', 0, 4], ['ACWTIME', 'V', 4, 4],
['ANSHOLDTIME', 'V', 8, 4], ['CONSULTTIME', 'V', 12, 4],
['DISPTIME', 'V', 16, 4], ['DURATION', 'V', 20, 4],
['SEGSTART', 'V', 24, 4], ['SEGSTOP', 'V', 28, 4],
['TALKTIME', 'V', 32, 4], ['NETINTIME', 'V', 36, 4],
['ORIGHOLDTIME', 'V', 40, 4],
#
# Extended ECHI R12 fields
#
['QUEUETIME', 'V', 44, 4], ['RINGTIME', 'V', 48, 4],
#
# End of Extended ECHI R12 fields
#
['DISPIVECTOR', 'v', 52, 2],
['DISPSPLIT', 'v', 54, 2], ['FIRSTVECTOR', 'v', 56, 2],
['SPLIT1', 'v', 58, 2], ['SPLIT2', 'v', 60, 2],
['SPLIT3', 'v', 62, 2], ['TKGRP', 'v', 64, 2],
['EQ_LOCID', 'v', 66, 2], ['ORIG_LOCID', 'v', 68, 2],
['ANS_LOCID', 'v', 70, 2], ['OBS_LOCID', 'v', 72, 2],
#
# Extended ECHI R12 field
#
['UUI_LEN', 'v', 74, 2],
#
# End of Extended ECHI R12 field
#
['ASSIST', 'b', 76, 1, 0], ['AUDIO', 'b', 76, 1, 1],
['CONFERENCE', 'b', 76, 1, 2], ['DA_QUEUED', 'b', 76, 1, 3],
['HOLDABN', 'b', 76, 1, 4], ['MALICIOUS', 'b', 76, 1, 5],
['OBSERVINGCALL', 'b', 76, 1, 6], ['TRANSFERRED', 'b', 76, 1, 7],
['AGT_RELEASED', 'b', 77, 1, 0], ['ACD', 'C', 78, 1],
['DISPOSITION', 'C', 79, 1], ['DISPPRIORITY', 'C', 80, 1],
['HELD', 'C', 81, 1], ['SEGMENT', 'C', 82, 1],
['ANSREASON', 'C', 83, 1], ['ORIGREASON', 'C', 84, 1],
['DISPSKLEVEL', 'C', 85, 1], ['EVENT1', 'C', 86, 1],
['EVENT2', 'C', 87, 1], ['EVENT3', 'C', 88, 1],
['EVENT4', 'C', 89, 1], ['EVENT5', 'C', 90, 1],
['EVENT6', 'C', 91, 1], ['EVENT7', 'C', 92, 1],
['EVENT8', 'C', 93, 1], ['EVENT9', 'C', 94, 1],
['UCID', 'Z*', 95, 21], ['DISPVDN', 'Z*', 116, 8],
['EQLOC', 'Z*', 124, 10], ['FIRSTVDN', 'Z*', 134, 8],
['ORIGLOGIN', 'Z*', 142, 10], ['ANSLOGIN', 'Z*', 152, 10],
['LASTOBSERVER', 'Z*', 162, 10], ['DIALED_NUM', 'Z*', 172, 25],
['CALLING_PTY', 'Z*', 197, 13], ['LASTDIGITS', 'Z*', 210, 17],
['LASTCWC', 'Z*', 227, 17], ['CALLING_II', 'Z*', 244, 3],
['CWC1', 'Z*', 247, 17], ['CWC2', 'Z*', 264, 17],
['CWC3', 'Z*', 281, 17], ['CWC4', 'Z*', 298, 17],
['CWC5', 'Z*', 315, 17],
#
# Extended ECHI R12 fields
#
['VDN2', 'Z*', 332, 8], ['VDN3', 'Z*', 340, 8],
['VDN4', 'Z*', 348, 8], ['VDN5', 'Z*', 356, 8],
['VDN6', 'Z*', 364, 8], ['VDN7', 'Z*', 372, 8],
['VDN8', 'Z*', 380, 8], ['VDN9', 'Z*', 388, 8],
['ASAI_UUI', 'Z*', 396, 96]
);
[...skipped...]
read(INFILE, $buf, 4); $version = unpack("V", $buf);
read(INFILE, $buf, 4); $sequence = unpack("V", $buf);
if ($version == 12 || $version == 11) {
print localtime() . " Processing file $ARGV[0], version $version, se
+quence $sequence\n";
} else {
die localtime() . " Unsupported file version $version, can't process
+!\n"
};
undef $buf;
my $rec_len = $version == 12 ? $ECHI_R12_LEN : $ECHI_R11_LEN;
my $echi_fmt = $version == 12 ? \@ECHI_R12_FMT : \@ECHI_R11_FMT;
my $processed = 0;
print_header(OUTFILE, $echi_fmt) unless !$PRINT_HEADER;
while(read(INFILE, $buf, $rec_len)) {
my %record = unpack_record($buf, $echi_fmt);
print localtime() . " Processing record $processed, Call ID " . $rec
+ord{'CALLID'} . ", Segment " . $record{'SEGMENT'} . "\n";
print_record(OUTFILE, \%record, $echi_fmt);
$processed++;
};
[...skipped...]
sub unpack_record {
my $buf = shift;
my $echi_format = shift;
my $echi_rec = undef;
my %record;
my $str = undef;
my $val = undef;
foreach $echi_field (@$echi_format) {
my $echi_name = @$echi_field[0];
my $echi_type = @$echi_field[1];
my $echi_offset = @$echi_field[2];
my $echi_len = @$echi_field[3];
my $echi_bitoffset = @$echi_field[4];
my $str = undef;
$str = substr($buf, $echi_offset, $echi_len);
if ($echi_type ne 'b') {
$val = unpack($echi_type, $str);
} else {
$val = vec($str, $echi_bitoffset, 8);
};
if ($echi_name =~ /SEG(START|STOP)/) {
$val = strftime($DATE_FORMAT, localtime($val)) unless !$DATE_FORMA
+T;
};
if ($echi_name =~ /SPLIT[1-3]/) { $val -= 65536 if ($val > 32767);
+ };
if ($echi_type =~ /Z/) {
$record{$echi_name} = "\"" . $val . "\"";
} else {
$record{$echi_name} = $val;
};
};
return %record;
};
sub print_header {
my $file = shift;
my $echi_format = shift;
my $line = "";
foreach $echi_field (@$echi_format) {
$line .= @$echi_field[0] . ",";
};
$line =~ s/,$//;
print $file "$line\n";
};
sub print_record {
my $file = shift;
my $record = shift;
my $echi_format = shift;
my $line = "";
foreach $echi_field (@$echi_format) {
$name = @$echi_field[0];
$line .= $record->{$name} . ",";
};
$line =~ s/,$//;
print $file "$line\n";
};
*blush* i guess my old pascal habits stick out... but at least it works. :) now, i was always told to optimize lately so now that i got working script i would like to optimize the hell out of it. that's the real fun. :)
|