File Coverage

blib/lib/Bayonne/Libexec.pm
Criterion Covered Total %
statement 12 317 3.7
branch 0 132 0.0
condition 0 39 0.0
subroutine 4 33 12.1
pod 0 29 0.0
total 16 550 2.9


line stmt bran cond sub pod time code
1             package Bayonne::Libexec;
2              
3 1     1   23640 use 5.008004;
  1         4  
  1         39  
4 1     1   4 use strict;
  1         2  
  1         29  
5 1     1   4 use warnings;
  1         5  
  1         43  
6              
7             require Exporter;
8 1     1   1816 use AutoLoader qw(AUTOLOAD);
  1         2621  
  1         6  
9              
10             our @ISA = qw(Exporter);
11              
12             # Items to export into callers namespace by default. Note: do not export
13             # names by default without a very good reason. Use EXPORT_OK instead.
14             # Do not simply export all your public functions/methods/constants.
15              
16             # This allows declaration use Bayonne::Libexec ':all';
17             # If you do not need this, moving things directly into @EXPORT or @EXPORT_OK
18             # will save memory.
19             our %EXPORT_TAGS = ( 'all' => [ qw(
20              
21             ) ] );
22              
23             our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } );
24              
25             our @EXPORT = qw(
26              
27             );
28            
29             our $VERSION = '0.03';
30              
31             # disable buffering
32             $|=1;
33              
34             sub new {
35 0     0 0   my ($class, %args) = @_;
36 0           my $self = {};
37 0           my ($buffer);
38             my ($num);
39              
40             # default voice
41 0           $self->{'voice'} = "";
42              
43             # digits buffer
44 0           $self->{'digits'} = "";
45              
46             # query buffer
47 0           $self->{'query'} = "";
48              
49             # audio position
50 0           $self->{'position'} = "00:00:00.000";
51              
52             # last header reply id number
53 0           $self->{'reply'} = 0;
54              
55             # last result code from a transaction.
56 0           $self->{'result'} = 0;
57              
58             # exit code if terminated by server, 0 if active
59 0           $self->{'exitcode'} = 0;
60              
61             # version of our interface
62 0           $self->{'version'} = "4.0";
63              
64             # audio level of tones...
65 0           $self->{'level'} = 0;
66              
67 0 0         $self->{'tsession'} = $ENV{'PORT_TSESSION'} if $ENV{'PORT_TSESSION'};
68            
69 0 0         if(!$self->{'tsession'}) {
70 0           $self->{'exitcode'} = 1;
71 0   0       bless $self, ref $class || $class;
72 0           return $self;
73             }
74              
75             # issue libexec HEAD request to get headers...
76              
77 0           print STDOUT "$self->{'tsession'} HEAD\n";
78 0           while()
79             {
80 0           $buffer = $_;
81 0           $num = 0;
82              
83 0 0 0       if(length($buffer) > 0 && substr($buffer, 0, 1) gt '0' && substr($buffer, 0, 1) le '9') {
      0        
84 0           $num = 0 + substr($buffer, 0, 3);
85             }
86              
87 0 0         if($num > 900) {
88 0           $self->{'reply'} = $num - 0;
89 0           $self->{'exitcode'} = $num - 900;
90 0           last;
91             }
92 0 0         if($num > 0) {
93 0           $self->{'reply'} = $num - 0;
94 0           next;
95             }
96 0 0         if($buffer eq "\n") {
97 0           last;
98             }
99 0           $_ =~ /(.*?)[:][ ](.*\n)/;
100 0           my($keyword, $value) = ($1, $2);
101 0           $value =~ s/\s+$//;
102 0 0         if($keyword eq "DIGITS") {
103 0           $self->{'digits'} = $value;
104             }
105 0           $self->{head}{$keyword}=$value;
106             }
107              
108             # issue libexec ARGS request to get command arguments...
109              
110 0           print STDOUT "$self->{'tsession'} ARGS\n";
111 0           while()
112             {
113 0           $buffer = $_;
114 0           $num = 0;
115 0 0 0       if(length($buffer) > 0 && substr($buffer, 0, 1) gt '0' && substr($buffer, 0, 1) le '9') {
      0        
116 0           $num = 0 + substr($buffer, 0, 3);
117             }
118 0 0         if($num > 900) {
119 0           $self->{'reply'} = $num - 0;
120 0           $self->{'exitcode'} = $num - 900;
121 0           last;
122             }
123 0 0         if($num > 0) {
124 0           $self->{'reply'} = $num - 0;
125 0           next;
126             }
127 0 0         if($buffer eq "\n") {
128 0           last;
129             }
130 0           $_ =~ /(.*?)[:][ ](.*\n)/;
131 0           my($keyword, $value) = ($1, $2);
132 0           $value =~ s/\s+$//;
133 0           $self->{args}{$keyword}=$value;
134             }
135            
136 0   0       bless $self, ref $class || $class;
137 0           return $self;
138             };
139              
140             # hangup
141              
142             sub hangup($) {
143 0     0 0   my($self) = @_;
144 0           my($tsid) = $self->{'tsession'};
145 0 0         if($tsid) {
146 0           print STDOUT "$tsid hangup\n";
147 0           $self->{'tsession'} = undef;
148             }
149             }
150              
151             # disconnect (server resumes...)
152              
153             sub detach($$) {
154 0     0 0   my($self,$code) = @_;
155 0           my($tsid) = $self->{'tsession'};
156              
157 0 0         if($tsid) {
158 0           print STDOUT "$tsid exit $code\n";
159 0           $self->{'tsession'} = undef;
160             }
161             }
162              
163             sub error($$) {
164 0     0 0   my($self,$msg) = @_;
165 0           my($tsid) = $self->{'tsession'};
166              
167 0 0         if($tsid) {
168 0           print STDOUT "$tsid error $msg\n";
169 0           $self->{'tsession'} = undef;
170             }
171             }
172              
173             sub post($$$) {
174 0     0 0   my($self, $id, $value) = @_;
175 0           my $sid = $self->{head}{'SESSION'};
176 0           print STDOUT "$sid POST $id $value\n";
177             }
178              
179             sub pathname($$) {
180 0     0 0   my($self,$file) = @_;
181 0           my $prefix = $self->{head}{'PREFIX'};
182 0           my $var = $ENV{'SERVER_PREFIX'};
183 0           my $ram = $ENV{'SERVER_TMPFS'};
184 0           my $tmp = $ENV{'SERVER_TMP'};
185 0           my $ext = $self->{head}{'EXTENSION'};
186              
187 0 0         if(!$file) {
188 0           return undef;
189             }
190              
191 0           my $spos = rindex $file, "/";
192 0           my $epos = rindex $file, ".";
193              
194 0 0         if($epos < $spos) {
195 0           $epos = -1;
196             }
197              
198 0 0         if($epos < 1) {
199 0           $file = "$file$ext";
200             }
201              
202 0 0         if(substr($file, 0, 4) eq "tmp:") {
203 0           my $sub = substr($file, 4);
204 0           return "$tmp/$sub";
205             }
206              
207 0 0         if(substr($file, 0, 4) eq "ram:") {
208 0           my $sub = substr($file, 4);
209 0           return "$ram/$sub";
210             }
211              
212 0           $_ = $file;
213 0           my $count = tr/://;
214 0 0         if($count > 0) {
215 0           return undef;
216             }
217              
218 0           $_ = $file;
219 0           $count = tr:/::;
220 0 0         if($count < 1) {
221 0 0 0       if(!$prefix or $prefix == "") {
222 0           return undef;
223             }
224 0           return "$var/$prefix/$file";
225             }
226 0           return "$var/$file";
227             }
228              
229             # check file validity for write/modify
230              
231             sub filename($$) {
232 0     0 0   my($self,$file) = @_;
233 0           my $prefix = $self->{head}{'PREFIX'};
234              
235 0 0         if(!$file) {
236 0           return undef;
237             }
238              
239 0 0         if(substr($file, 0, 4) eq "tmp:") {
240 0           return $file;
241             }
242              
243 0 0         if(substr($file, 0, 4) eq "ram:") {
244 0           return $file;
245             }
246              
247 0 0         if(substr($file, 0, 1) eq "/") {
248 0           return undef;
249             }
250              
251 0           $_ = $file;
252 0           my $count = tr/://;
253 0 0         if($count > 0) {
254 0           return undef;
255             }
256              
257 0           $_ = $file;
258 0           $count = tr:/::;
259 0 0 0       if($count == 0 && !$prefix) {
260 0           return undef;
261             }
262              
263 0 0         if($count == 0) {
264 0           return "$prefix/$file";
265             }
266              
267 0           return "$file";
268             }
269              
270             # move files
271              
272             sub move($$$) {
273 0     0 0   my ($self,$file1,$file2) = @_;
274 0           $file1 = $self->pathname($file1);
275 0           $file2 = $self->pathname($file2);
276 0 0 0       if(!$file1 || !$file2) {
277 0           $self->{'result'} = 254;
278 0           return 254;
279             }
280 0           rename($file1, $file2);
281 0           $self->{'result'} = 0;
282 0           return 0;
283             }
284              
285             # erase file
286              
287             sub erase($$) {
288 0     0 0   my ($self,$file) = @_;
289 0           $file = $self->pathname($file);
290 0 0         if(!$file) {
291 0           $self->{'result'} = 254;
292 0           return 254;
293             }
294 0           remove("$file");
295 0           $self->{'result'} = 0;
296 0           return 0;
297             }
298              
299             # play audio tone
300              
301             sub tone {
302 0     0 0   my $self = shift;
303 0           my $tone = shift;
304 0           my $duration = shift;
305 0           my $level = shift;
306              
307 0 0         if(!$duration) {
308 0           $duration = 0;
309             }
310              
311 0 0         if(!$level) {
312 0           $level = $self->{'level'};
313             }
314 0           return $self->command("tone $tone $duration $level");
315             }
316              
317             sub single_tone {
318 0     0 0   my $self = shift;
319 0           my $tone = shift;
320 0           my $duration = shift;
321 0           my $level = shift;
322              
323 0 0         if(!$duration) {
324 0           $duration = 0;
325             }
326              
327 0 0         if(!$level) {
328 0           $level = $self->{'level'};
329             }
330 0           return $self->command("stone $tone $duration $level");
331             }
332              
333             sub dual_tone {
334 0     0 0   my $self = shift;
335 0           my $tone1 = shift;
336 0           my $tone2 = shift;
337 0           my $duration = shift;
338 0           my $level = shift;
339              
340 0 0         if(!$duration) {
341 0           $duration = 0;
342             }
343              
344 0 0         if(!$level) {
345 0           $level = $self->{'level'};
346             }
347 0           return $self->command("dtone $tone1 $tone2 $duration $level");
348             }
349              
350             # replay audio
351              
352             sub replay {
353 0     0 0   my $self = shift;
354 0           my $file = shift;
355 0           my $offset = undef;
356              
357 0           $file = $self->filename($file);
358              
359 0 0         if(!$file) {
360 0           $self->{'result'} = 254;
361 0           return "255";
362             }
363              
364 0 0         if($offset) {
365 0           return $self->command("replay $file $offset");
366             } else {
367 0           return $self->command("replay $file");
368             }
369             }
370              
371             # record audio
372              
373             sub record {
374 0     0 0   my $self = shift;
375 0           my $file = shift;
376 0           my $timeout = shift;
377 0           my $silence = undef;
378 0           my $offset = undef;
379              
380 0           $file = $self->filename($file);
381              
382 0 0         if(!$file) {
383 0           $self->{'result'} = 254;
384 0           return "254";
385             }
386              
387 0 0         if($timeout) {
388 0           $silence = shift;
389 0 0         if($silence) {
390 0           $offset = shift;
391             }
392             }
393              
394 0 0         if(!$timeout) {
395 0           $timeout = 60;
396             }
397              
398 0 0         if(!$silence) {
399 0           $silence = 0;
400             }
401              
402 0 0         if($offset) {
403 0           return $self->command("record $file $timeout $silence $offset");
404             } else {
405 0           return $self->command("record $file $timeout $silence");
406             }
407             }
408              
409             # set voice to use, undef to reset...
410              
411             sub voice {
412 0     0 0   my $self = shift;
413 0           my $voice = shift;
414              
415 0           $self->{'voice'} = $voice;
416             }
417              
418             sub level($$) {
419 0     0 0   my($self, $level) = @_;
420 0           $self->{'level'} = $level;
421             }
422              
423             # process input line
424              
425             sub input($$$) {
426 0     0 0   my ($self, $count, $timeout) = @_;
427              
428 0 0         if(!$count) {
429 0           $count = 1;
430             }
431              
432 0 0         if(!$timeout) {
433 0           $timeout = 0;
434             }
435              
436 0           my $result = $self->command("READ $timeout $count");
437 0 0         if($result != 0) {
438 0           return "";
439             }
440              
441 0           return $self->{'digits'};
442             }
443              
444             # clear pending input
445              
446             sub clear($) {
447 0     0 0   my($self) = @_;
448 0           return $self->command("FLUSH");
449             }
450              
451             # wait for a key event
452              
453             sub wait($$) {
454 0     0 0   my ($self, $timeout) = @_;
455              
456 0 0         if(!$timeout) {
457 0           $timeout = 0;
458             }
459 0           my $result = $self->command("WAIT $timeout");
460 0 0         if($result == 3) {
461 0           return 1;
462             }
463 0           return 0;
464             }
465              
466             # process single key input
467              
468             sub inkey($$) {
469 0     0 0   my ($self, $timeout) = @_;
470              
471 0 0         if(!$timeout) {
472 0           $timeout = 0;
473             }
474              
475 0           my $result = $self->command("READ $timeout");
476 0 0         if($result != 0) {
477 0           return "";
478             }
479 0           return substr($self->{'digits'}, 0, 1);
480             }
481              
482             # send results back to server.
483              
484             sub result($$) {
485 0     0 0   my($self, $buf) = @_;
486 0           $buf =~ s/\%/\%\%/g;
487 0 0         $buf =~ s/(.)/ord $1 < 32 ?
  0            
488             sprintf "%%%s", chr(ord($1) + 64) : sprintf "%s",$1/eg;
489              
490 0           return $self->command("result $buf");
491             }
492              
493             # transfer extension
494              
495             sub transfer($$) {
496 0     0 0   my($self, $dest) = @_;
497 0           return $self->command("xfer $dest");
498             }
499              
500             # get symbol value
501              
502             sub get($$) {
503 0     0 0   my($self, $buf) = @_;
504 0           $self->command("get $buf");
505 0           return $self->{'query'};
506             }
507              
508             # set symbol value
509              
510             sub set($$$) {
511 0     0 0   my($self, $id, $value) = @_;
512 0           return $self->command("set $id $value");
513             }
514              
515             sub add($$$) {
516 0     0 0   my($self, $id, $value) = @_;
517 0           return $self->command("add $id $value");
518             }
519              
520             # size a symbol
521              
522             sub size($$$) {
523 0     0 0   my($self, $id, $buf) = @_;
524 0           my($size) = $buf - 0;
525 0           return $self->command("new $id $size");
526             }
527            
528             # build prompt
529              
530             sub speak($$) {
531 0     0 0   my($self, $buf) = @_;
532 0           my($voice) = $self->{'voice'};
533              
534 0 0         if(!$voice) {
535 0           $voice = "prompt";
536             }
537              
538 0 0         if($voice eq "") {
539 0           $voice = "prompt";
540             }
541              
542 0           return $self->command("$voice $buf");
543             }
544              
545             # issue a libexec command and parse the transaction results.
546              
547             sub command($$) {
548 0     0 0   my($self,$buf) = @_;
549 0           my($hid) = 0;
550 0           my($result) = 255; # no result value
551 0           my($tsession) = $self->{'tsession'};
552 0           my($exitcode) = $self->{'exitcode'};
553 0           my($buffer);
554             my($num);
555              
556 0 0 0       if(!$tsession || $exitcode > 0) {
557 0           return -$exitcode;
558             }
559 0           $buf =~ s/\%/\%\%/g;
560 0 0         $buf =~ s/(.)/ord $1 < 32 ?
  0            
561             sprintf "%%%s", chr(ord($1) + 64) : sprintf "%s",$1/eg;
562              
563 0           $self->{'query'} = "";
564 0           print STDOUT "$tsession $buf\n";
565              
566 0           while()
567             {
568 0           $buffer = $_;
569 0           $num = 0;
570 0 0 0       if(length($buffer) > 0 && substr($buffer, 0, 1) gt '0' && substr($buffer, 0, 1) le '9') {
      0        
571 0           $num = 0 + substr($buffer, 0, 3);
572             }
573            
574 0 0         if($num > 900) {
575 0           $self->{'reply'} = $num - 0;
576 0           $self->{'exitcode'} = $num - 900;
577 0           last;
578             }
579 0 0         if($num > 0) {
580 0           $self->{'reply'} = $num - 0;
581 0           $hid = $num - 0;
582 0           next;
583             }
584 0 0         if($buffer eq "\n") {
585 0           last;
586             }
587 0 0 0       if($hid != 100 && $hid != 400) {
588 0           next;
589             }
590 0           $_ =~ /(.*?)[:][ ](.*\n)/;
591 0           my($keyword, $value) = ($1, $2);
592 0           $value =~ s/\s+$//;
593 0           $keyword = lc($keyword);
594 0 0         if($hid == 400) {
595 0           $keyword = "query";
596             }
597 0 0         if($keyword eq "result") {
598 0           $result = $value - 0;
599             }
600 0           $self->{$keyword}=$value;
601             }
602 0           return $result;
603             }
604              
605             # generic print function, works whether in TGI or direct execute mode
606              
607             sub print($$) {
608 0     0 0   my($self,$buf) = @_;
609 0           $buf =~ s/\%/\%\%/g;
610 0 0         $buf =~ s/(.)/ord $1 < 32 ?
  0            
611             sprintf "%%%s", chr(ord($1) + 64) : sprintf "%s",$1/eg;
612 0 0         if($self->{'tsession'}) {
613 0           print STDERR $buf;
614             } else {
615 0           print STDOUT $buf;
616             }
617             }
618             1;
619             __END__