File Coverage

CTPort.pm
Criterion Covered Total %
statement 23 392 5.8
branch 1 86 1.1
condition 1 6 16.6
subroutine 7 50 14.0
pod 0 42 0.0
total 32 576 5.5


line stmt bran cond sub pod time code
1             package Telephony::CTPort;
2              
3             # CTPort - part of ctserver client/server library for Computer Telephony
4             # programming in Perl
5             #
6             # Copyright (C) 2001-2003 David Rowe
7             #
8             # This library is free software; you can redistribute it and/or
9             # modify it under the terms of the GNU Lesser General Public
10             # License as published by the Free Software Foundation; either
11             # version 2.1 of the License, or (at your option) any later version.
12             #
13             # This library is distributed in the hope that it will be useful,
14             # but WITHOUT ANY WARRANTY; without even the implied warranty of
15             # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16             # Lesser General Public License for more details.
17             #
18             # You should have received a copy of the GNU Lesser General Public
19             # License along with this library; if not, write to the Free Software
20             # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21              
22             require 5.005_62;
23             #use strict;
24 1     1   1061 use warnings;
  1         2  
  1         32  
25 1     1   6 use Carp;
  1         1  
  1         98  
26 1     1   1063 use IO::Socket;
  1         26350  
  1         5  
27 1     1   490 use IO::Handle;
  1         1  
  1         38  
28 1     1   6 use Cwd qw(cwd);
  1         1  
  1         41  
29 1     1   723 use POSIX;
  1         7960  
  1         5  
30              
31             require Exporter;
32              
33             our @ISA = qw(Exporter);
34              
35             # Items to export into callers namespace by default. Note: do not export
36             # names by default without a very good reason. Use EXPORT_OK instead.
37             # Do not simply export all your public functions/methods/constants.
38              
39             # This allows declaration use Telephony::CTPort ':all';
40             # If you do not need this, moving things directly into @EXPORT or @EXPORT_OK
41             # will save memory.
42             our %EXPORT_TAGS = ( 'all' => [ qw( ) ] );
43              
44             our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } );
45              
46             our @EXPORT = qw( );
47             our $VERSION = '1.01';
48              
49             # Preloaded methods go here.
50              
51             # constructor - opens TCP/IP connection to server and makes sure we are
52             # on hook to start with
53             sub new($) {
54 1     1 0 59 my $proto = shift;
55 1         2 our $port = shift;
56 1   33     8 my $class = ref($proto) || $proto;
57 1         2 my $self = {};
58              
59 1 50       14 $self->{SERVER} = IO::Socket::INET->new(
60             Proto => "tcp",
61             PeerAddr => "localhost",
62             PeerPort => $port,
63             )
64             or croak "cannot connect to server tcp port $port";
65              
66 0           $self->{EVENT} = undef;
67 0           $self->{DEF_EXT} = ".au"; # default audio file extension
68 0           $self->{PATHS} = []; # user supplied audio file paths
69 0           $self->{INTER_DIGIT} = undef;
70 0           $self->{DEFEVENTS} = undef; # Used to hold default event handlers
71 0           $self->{CONFIG} = undef; # Used to hold Config values
72 0           $self->{DAEMON} = undef; # Used to hold daemon state
73              
74 0           bless($self, $class);
75 0           return $self;
76             }
77              
78             sub set_def_ext($) {
79 0     0 0   my $self = shift;
80 0           my $defext = shift;
81 0           $self->{DEF_EXT} = $defext;
82             }
83              
84             sub set_paths($) {
85 0     0 0   my $self = shift;
86 0           my $paths = shift;
87 0           $self->{PATHS} = $paths;
88             }
89              
90             sub set_event_handler(){
91 0     0 0   my $self = shift;
92 0           my $event = shift;
93 0           my $handle = shift;
94 0           $self->{DEFEVENT}{$event}=$handle;
95             }
96              
97             sub unset_event_handler(){
98 0     0 0   my $self = shift;
99 0           my $event = shift;
100 0           $self->{DEFEVENT}{$event}=undef;
101             }
102              
103             sub event($) {
104 0     0 0   my $self = shift;
105 0           return $self->{EVENT};
106             }
107              
108             sub off_hook() {
109 0     0 0   my $self = shift;
110 0           my $buf;
111 0           my $server = $self->{SERVER};
112 0           print $server "ctanswer\n";
113 0           $buf = <$server>;
114             }
115              
116             sub on_hook() {
117 0     0 0   my $self = shift;
118 0           my $buf;
119 0           my $server = $self->{SERVER};
120 0           print $server "cthangup\n";
121 0           $buf = <$server>;
122             }
123              
124             sub wait_for_ring() {
125 0     0 0   my $self = shift;
126 0           my $server = $self->{SERVER};
127 0           my $caller_id;
128 0           print $server "ctwaitforring\n";
129 0           $caller_id = <$server>;
130 0           return $caller_id;
131             }
132              
133             sub wait_for_dial_tone() {
134 0     0 0   my $self = shift;
135 0           my $server = $self->{SERVER};
136 0           my $buf;
137 0           print $server "ctwaitfordial\n";
138 0           $buf = <$server>;
139             }
140              
141             sub play_busy_tone_async(){
142 0     0 0   my $self = shift;
143 0           my $server = $self->{SERVER};
144 0           print $server "ctplaytoneasync\nbusy\n";
145 0           my $tmp=<$server>;
146 0           return($tmp);
147             }
148              
149             sub play_dialx_tone_async(){
150 0     0 0   my $self = shift;
151 0           my $server = $self->{SERVER};
152 0           print $server "ctplaytoneasync\ndialx\n";
153             }
154              
155             sub play_dial_tone_async(){
156 0     0 0   my $self = shift;
157 0           my $server = $self->{SERVER};
158 0           print $server "ctplaytoneasync\ndial\n";
159             }
160              
161             sub play_ringback_async(){
162 0     0 0   my $self = shift;
163 0           my $server = $self->{SERVER};
164 0           print $server "ctplaytoneasync\nringback\n";
165 0           my $tmp=<$server>;
166 0           return($tmp);
167             }
168              
169             sub play_terminate(){
170 0     0 0   my $self = shift;
171 0           my $server = $self->{SERVER};
172 0           print $server "ctstoptone\n";
173 0           my $tmp=<$server>;
174 0           return($tmp);
175             }
176              
177             sub play_stop(){
178 0     0 0   my $self = shift;
179 0           my $server = $self->{SERVER};
180 0           print $server "ctplay_stop\n";
181 0           my $tmp=<$server>;
182 0           return($tmp);
183             }
184              
185             sub play_async($) {
186 0     0 0   my $self = shift;
187 0           my $files_str = shift;
188 0           my $file;
189              
190 0 0         unless (length($files_str)) {return;}
  0            
191              
192 0           foreach $file (split(/ /,$files_str)){
193 0           $self->_ctplayonefile_async($file);
194             }
195             }
196              
197             sub _ctplayonefile_async() {
198 0     0     my $self = shift;
199 0           my $file = shift;
200 0           my $server = $self->{SERVER};
201 0           my $event;
202             my $path;
203              
204             # append default extension if no extension on file name
205 0 0         if ($self->{DEF_EXT}) {
206 0 0         if ($file !~ /\./) {
207 0           $file = $file . $self->{DEF_EXT};
208             }
209             }
210              
211             # check user supplied paths
212 0 0         if (defined($self->{PATHS})) {
213 0           my @paths = $self->{PATHS};
214 0           foreach $path (@paths) {
215             # find first path that contains the file
216 0 0         if (-e "$path/$file") {
217 0           print $server "ctplay_async\n$path/$file\n";
218 0           $event = <$server>;
219 0           $event =~ s/[^0-9ABCD#*]//g;
220 0           $self->{EVENT} = $event;
221 0           return;
222             }
223             }
224             }
225              
226             # check default paths
227 0 0         if (-e "$ENV{PWD}/$file") {
228             # full path supplied by caller
229 0           print $server "ctplay_async\n$ENV{PWD}/$file\n";
230 0           $event = <$server>;
231 0           $event =~ s/[^0-9ABCD#*]//g;
232 0           $self->{EVENT} = $event;
233 0           return;
234             }
235              
236 0 0         if (-e "$ENV{PWD}/prompts/$file") {
237             # prompts sub-dir of current dir
238 0           print $server "ctplay_async\n$ENV{PWD}/prompts/$file\n";
239 0           $event = <$server>;
240 0           $event =~ s/[^0-9ABCD#*]//g;
241 0           $self->{EVENT} = $event;
242 0           return;
243             }
244              
245 0 0         if (-e "/var/ctserver/USEngM/$file") {
246             # USEngM prompts dir
247 0           print $server "ctplay_async\n/var/ctserver/USEngM/$file\n";
248 0           $event = <$server>;
249 0           $event =~ s/[^0-9ABCD#*]//g;
250 0           $self->{EVENT} = $event;
251 0           return;
252             }
253              
254 0           return -1;
255             }
256              
257             sub play($) {
258 0     0 0   my $self = shift;
259 0           my $files_str = shift;
260 0           my $file;
261              
262 0 0         unless (length($files_str)) {return;}
  0            
263 0           my @files_array = split(/ /,$files_str);
264              
265 0           foreach $file (@files_array) {
266 0 0         if (!$self->{EVENT}) {
267 0           $self->_ctplayonefile($file);
268             }
269             }
270             }
271              
272             sub _ctplayonefile() {
273 0     0     my $self = shift;
274 0           my $file = shift;
275 0           my $server = $self->{SERVER};
276 0           my $event;
277             my $path;
278              
279             # append default extension if no extension on file name
280 0 0         if ($self->{DEF_EXT}) {
281 0 0         if ($file !~ /\./) {
282 0           $file = $file . $self->{DEF_EXT};
283             }
284             }
285              
286             # check user supplied paths
287 0 0         if (defined($self->{PATHS})) {
288 0           my @paths = $self->{PATHS};
289 0           foreach $path (@paths) {
290             # find first path that contains the file
291 0 0         if (-e "$path/$file") {
292 0           print $server "ctplay\n$path/$file\n";
293 0           $event = <$server>;
294 0           $event =~ s/[^0-9ABCD#*]//g;
295 0           $self->{EVENT} = $event;
296 0           return;
297             }
298             }
299             }
300              
301             # check default paths
302 0 0         if (-e "$ENV{PWD}/$file") {
303             # full path supplied by caller
304 0           print $server "ctplay\n$ENV{PWD}/$file\n";
305 0           $event = <$server>;
306 0           $event =~ s/[^0-9ABCD#*]//g;
307 0           $self->{EVENT} = $event;
308 0           return;
309             }
310              
311 0 0         if (-e "$ENV{PWD}/prompts/$file") {
312             # prompts sub-dir of current dir
313 0           print $server "ctplay\n$ENV{PWD}/prompts/$file\n";
314 0           $event = <$server>;
315 0           $event =~ s/[^0-9ABCD#*]//g;
316 0           $self->{EVENT} = $event;
317 0           return;
318             }
319              
320 0 0         if (-e "/var/ctserver/USEngM/$file") {
321             # USEngM prompts dir
322 0           print $server "ctplay\n/var/ctserver/USEngM/$file\n";
323 0           $event = <$server>;
324 0           $event =~ s/[^0-9ABCD#*]//g;
325 0           $self->{EVENT} = $event;
326 0           return;
327             }
328              
329 0           print "play: File $file not found!\n";
330             }
331              
332             sub record($$$) {
333 0     0 0   my $self = shift;
334 0           my $file = shift;
335 0           my $timeout = shift;
336 0           my $term_digits = shift;
337 0           my $server = $self->{SERVER};
338 0           my $event;
339 0           my @unpacked_file = split(//, $file);
340              
341 0 0         unless ($unpacked_file[0] eq "/") {
342             # if not full path, record in current dir
343 0           $file = "$ENV{PWD}/$file";
344             }
345 0           print $server "ctrecord\n$file\n$timeout\n$term_digits\n";
346 0           $event = <$server>;
347 0           $event =~ s/[^0-9ABCD#*]//g;
348 0           $self->{EVENT} = $event;
349             }
350              
351             sub ctsleep($) {
352 0     0 0   my $self = shift;
353 0           my $secs = shift;
354 0           my $server = $self->{SERVER};
355 0           my $event;
356 0 0         if (!$self->{EVENT}) {
357 0           print $server "ctsleep\n$secs\n";
358 0           $event = <$server>;
359 0           $event =~ s/[^0-9ABCD#*]//g;
360 0           $self->{EVENT} = $event;
361             }
362             }
363              
364             sub clear() {
365 0     0 0   my $self = shift;
366 0           my $server = $self->{SERVER};
367 0           my $tmp;
368 0           print $server "ctclear\n";
369 0           $tmp = <$server>;
370 0           undef $self->{EVENT};
371             }
372              
373             sub collect($$) {
374 0     0 0   my $self = shift;
375 0           my $maxdigits = shift;
376 0           my $maxseconds = shift;
377 0           my $maxinter;
378 0           my $server = $self->{SERVER};
379 0           my $digits ="OK";
380              
381 0   0       $maxinter = $self->{INTER_DIGIT} || $maxseconds;
382 0           undef $self->{EVENT};
383              
384 0           print $server "ctcollect\n$maxdigits\n$maxseconds\n$maxinter\n";
385 0           while ($digits =~ /OK/){
386 0           $digits = <$server>;
387             }
388 0           $digits =~ s/[^0-9ABCD#*]//g;
389 0           return $digits;
390             }
391              
392             sub dial($) {
393 0     0 0   my $self = shift;
394 0           my($dial_str) = shift;
395 0           my $server = $self->{SERVER};
396 0           my($tmp);
397 0           print $server "ctdial\n$dial_str\n";
398 0           $tmp = <$server>;
399 0           return($tmp);
400             }
401              
402             sub number($) {
403 0     0 0   my $self = shift;
404 0           my $num = shift;
405 0           my $server = $self->{SERVER};
406 0           my $tens;
407             my $hundreds;
408 0           my @files;
409 0           my $all;
410 0 0         unless ($num) {return undef};
  0            
411 0 0         if ($num == 0) { push(@files, $num); }
  0            
412              
413 0           $hundreds = int($num/100) * 100;
414 0           $num = $num - $hundreds;
415 0 0         if ($hundreds != 0) { push(@files, $hundreds); }
  0            
416 0           $tens = int($num/10) * 10;
417 0 0         if ($num > 20) {
418 0           $num = $num - $tens;
419 0 0         if ($tens != 0) { push(@files, $tens); }
  0            
420             }
421 0 0         if ($num != 0) { push(@files, $num); }
  0            
422 0           $all = "@files";
423 0           return $all;
424             }
425              
426             sub get_inter_digit_time_out() {
427 0     0 0   my $self = shift;
428 0           return $self->{INTER_DIGIT};
429             }
430              
431             sub set_inter_digit_time_out($) {
432 0     0 0   my $self = shift;
433 0           my $inter = shift;
434 0           $self->{INTER_DIGIT} = $inter;
435             }
436              
437             sub wait_for_event() {
438 0     0 0   my $self = shift;
439 0           my $server = $self->{SERVER};
440 0           my $handle = "";
441              
442 0           WEWL:
443             print $server "ctwaitforevent\n";
444 0           while($handle eq ""){
445 0           $handle = <$server>;
446 0 0         if (!defined($handle)) {
447 0           exit;
448             }
449 0           $handle =~ s/[^0-9a-z ]//g;
450             }
451 0           my $event = <$server>;
452 0           $event =~ s/[^0-9a-z ]//g;
453 0 0         if (defined $self->{DEFEVENT}{$event}){
454 0           my $foo="main::".$self->{DEFEVENT}{$event};
455 0           &{$foo}($handle);
  0            
456 0           $self->{EVENT} = $event;
457 0           undef $event;
458 0           $handle="";
459 0           goto WEWL;
460             }
461 0           $self->{EVENT} = $event;
462 0           return ($handle,$event);
463             }
464              
465             sub send_event($$) {
466 0     0 0   my $self = shift;
467 0           my $port = shift;
468 0           my $event = shift;
469 0           my $server = $self->{SERVER};
470 0           my $tmp;
471              
472 0           print $server "ctsendevent\n$port\n$event\n";
473 0           $tmp = <$server>;
474             }
475              
476             sub start_timer_async($) {
477 0     0 0   my $self = shift;
478 0           my $duration = shift;
479 0           my $server = $self->{SERVER};
480 0           my $tmp;
481              
482 0           print $server "ctstarttimerasync\n$duration\n";
483 0           $tmp = <$server>;
484 0           return($tmp);
485             }
486              
487             sub stop_timer() {
488 0     0 0   my $self = shift;
489 0           my $server = $self->{SERVER};
490 0           my $tmp;
491              
492 0           print $server "ctstoptimer\n";
493 0           $tmp = <$server>;
494 0           return($tmp);
495             }
496              
497             sub play_tone_async($) {
498 0     0 0   my $self = shift;
499 0           my $tone = shift;
500 0           my $server = $self->{SERVER};
501 0           my $tmp;
502              
503 0           print $server "ctplaytoneasync\n$tone\n";
504 0           $tmp = <$server>;
505 0           return($tmp);
506             }
507              
508             sub stop_tone() {
509 0     0 0   my $self = shift;
510 0           my $server = $self->{SERVER};
511 0           my $tmp;
512              
513 0           print $server "ctstoptone\n";
514 0           $tmp = <$server>;
515 0           return($tmp);
516             }
517              
518             sub join($$) {
519 0     0 0   my $self = shift;
520 0           my $port = shift;
521 0           my $port2 = shift;
522 0           my $server = $self->{SERVER};
523 0           my $tmp;
524              
525 0           print $server "ctjoin\n $port \n $port2 \n";
526 0           $tmp = <$server>;
527 0           return($tmp);
528             }
529              
530             sub bridge($) {
531 0     0 0   my $self = shift;
532 0           my $port = shift;
533 0           my $server = $self->{SERVER};
534 0           my $tmp;
535              
536 0           print $server "ctbridge\n$port\n";
537 0           $tmp = <$server>;
538 0           return($tmp);
539             }
540              
541             sub unbridge($) {
542 0     0 0   my $self = shift;
543 0           my $port = shift;
544 0           my $server = $self->{SERVER};
545 0           my $tmp;
546 0 0         if ($port <0){
547 0           return("NOK");
548             }
549              
550 0           print $server "ctunbridge\n$port\n";
551 0           $tmp = <$server>;
552 0           return($tmp);
553             }
554              
555             sub start_ring_async($) {
556 0     0 0   my $self = shift;
557 0           my $server = $self->{SERVER};
558 0           my $tmp;
559              
560 0           print $server "ctstartringasync\n";
561 0           $tmp = <$server>;
562 0           return($tmp);
563             }
564              
565             sub stop_ring($) {
566 0     0 0   my $self = shift;
567 0           my $server = $self->{SERVER};
568 0           my $tmp;
569              
570 0           print $server "ctstopring\n";
571 0           $tmp = <$server>;
572 0           return($tmp);
573             }
574              
575             sub start_ring_once_async() {
576 0     0 0   my $self = shift;
577 0           my $server = $self->{SERVER};
578 0           my $tmp;
579              
580 0           print $server "ctstartringonceasync\n";
581 0           $tmp = <$server>;
582 0           return($tmp);
583             }
584              
585             sub getconf($){
586 0     0 0   my $self = shift;
587 0           my $file = shift;
588 0           my ($line,$section,$tag,$value);
589 0 0         if (!defined $conffile){
590 0           our $conffile = cwd();
591 0           $conffile=$conffile."/".$file;
592             }
593 0 0         open(FILE,"< $conffile") || die "Can't open $conffile : $!\n";
594 0           foreach $line (){
595 0           chomp $line;
596 0 0         if ($line =~ /^\s*#/){
    0          
    0          
597 0           next;
598             }
599             elsif($line =~ /^\s*\[\w+\]/){
600 0           $section=$line;
601 0           $section =~ s/[\[\]]//g;
602             }
603             elsif($line =~ /(\w+)=(\w+)/){
604 0           ($tag, $value)= split /=/,$line;
605 0           $self->{CONFIG}->{$section}{$tag} = $value;
606             }
607             }
608 0           close FILE;
609 0           return(1);
610             }
611              
612             sub daemonize($){
613 0     0 0   my $self = shift;
614 0           my $bool = shift;
615 0 0         if ($bool == 1){
616             # make a daemon
617 0 0         defined(my $pid = fork) or die "Can't fork: $!";
618 0 0         exit if $pid;
619 0 0         setsid or die "Can't start a new session: $!";
620 0 0         chdir '/' or die "Can't chdir to /: $!";
621 0           umask 0;
622 0 0         open STDIN, '/dev/null' or die "Can't read /dev/null: $!";
623 0 0         open STDOUT, '/dev/null' or die "Can't write to /dev/null: $!";
624 0 0         open STDERR, '/dev/null' or die "Can't write to /dev/null: $!";
625             }
626 0           $self->{DAEMON}=1;
627 0           return(1);
628             }
629              
630             sub openlogger($){
631 0     0 0   my $self = shift;
632 0           my $logfile = shift;
633 0           open (our $LOGFILE,">$logfile");
634 0           autoflush $LOGFILE 1;
635             }
636              
637             sub logger($){
638 0     0 0   my $self = shift;
639 0           my $text = shift;
640 0           my $foo = strftime("%Y/%m/%d-%H:%M:%S",localtime(time));
641 0 0         if ($self->{DAEMON}){
642 0           print $LOGFILE "$foo [".$port."] $text\n";
643             }
644             else {
645 0           print STDERR "$foo [".$port."] $text\n";
646             }
647             }
648              
649             1;
650              
651             __END__