File Coverage

blib/lib/VoiceXML/Client/DeviceHandle.pm
Criterion Covered Total %
statement 33 138 23.9
branch 5 34 14.7
condition 1 14 7.1
subroutine 7 29 24.1
pod 12 24 50.0
total 58 239 24.2


line stmt bran cond sub pod time code
1             package VoiceXML::Client::DeviceHandle;
2              
3 3     3   16 use VoiceXML::Client;
  3         6  
  3         85  
4 3     3   1687 use VoiceXML::Client::Util;
  3         6  
  3         75  
5 3     3   1599 use VoiceXML::Client::Vars;
  3         14  
  3         72  
6              
7 3     3   13 use strict;
  3         5  
  3         100  
8              
9             # just need to define an interface for device handles...
10             # this really only tells you where to look for the API
11              
12 3         4971 use vars qw {
13             $DeviceDefined
14             %InputMode
15             %ReadnumGlobals
16             $VERSION
17 3     3   15 };
  3         4  
18              
19             $DeviceDefined = 1;
20             %InputMode = (
21             'FIXEDDIGIT' => 1,
22             'MULTIDIGIT' => 2,
23             );
24              
25             $VERSION = $VoiceXML::Client::VERSION;
26              
27             =head1 VoiceXML::Client::DeviceHandle
28              
29             =head1 NAME
30              
31             VoiceXML::Client::DeviceHandle - Encapsulates the communications device (eg Voice Modem)
32              
33              
34             =head1 SYNOPSIS
35              
36             The VoiceXML::Client::DeviceHandle module is meant to serve as an abstract base
37             class for voice communication devices.
38            
39             It provides the interface VoiceXML::Client::DeviceHandle::XXX modules are expected
40             to implement.
41              
42             =head1 AUTHOR
43              
44             LICENSE
45              
46             VoiceXML::Client::DeviceHandle module, device handle api based on the VOCP voice messaging system package
47             VOCP::Device.
48            
49             Copyright (C) 2002,2008 Patrick Deegan
50             All rights reserved
51              
52              
53             This file is part of VoiceXML::Client.
54            
55             VoiceXML::Client is free software: you can redistribute it and/or modify
56             it under the terms of the GNU General Public License as published by
57             the Free Software Foundation, either version 3 of the License, or
58             (at your option) any later version.
59              
60             VoiceXML::Client is distributed in the hope that it will be useful,
61             but WITHOUT ANY WARRANTY; without even the implied warranty of
62             MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
63             GNU General Public License for more details.
64              
65             You should have received a copy of the GNU General Public License
66             along with VoiceXML::Client. If not, see .
67              
68              
69              
70             =head2 new [PARAMHREF]
71              
72             Creates a new instance, calling init() with PARAMHREF if passed.
73             Returns a new blessed object.
74              
75             =cut
76              
77             sub new {
78 3     3 1 3701 my $class = shift;
79 3         7 my $params = shift;
80            
81 3         8 my $self = {};
82            
83 3   33     34 bless $self, ref $class || $class;
84            
85            
86 3 50       33 $self->{'autostop'} = (defined $params->{'autostop'}) ? $params->{'autostop'} : $VoiceXML::Client::Vars::Defaults{'autostop'};
87            
88 3 50       18 $self->{'timeout'} = (defined $params->{'timeout'}) ? $params->{'timeout'} : $VoiceXML::Client::Vars::Defaults{'timeout'};
89            
90 3 50       13 $self->{'numrepeat'} = (defined $params->{'numrepeat'}) ? $params->{'numrepeat'} : $VoiceXML::Client::Vars::Defaults{'numrepeat'};
91            
92 3 50       48 $self->{'device'} = (defined $params->{'device'}) ? $params->{'device'} : $VoiceXML::Client::Vars::Defaults{'device'};
93            
94 3 50       20 $self->{'inputmode'} = (defined $params->{'inputmode'}) ? $params->{'inputmode'} : $InputMode{'FIXEDDIGIT'};
95            
96 3         8 while (my ($key, $val) = each %{$params})
  3         19  
97             {
98 0         0 $self->{$key} = $val;
99             }
100              
101            
102 3         24 $ReadnumGlobals{$$}{'device_obj'} = $self;
103            
104            
105 3         11 $ReadnumGlobals{$$}{'inputReceivedCallbacks'} = {};
106            
107            
108 3         34 $self->init($params);
109            
110            
111 3         11 return $self;
112             }
113              
114              
115             =head2 init PARAMHREF
116              
117             Called by new(). This method is used in derived classes to perform startup initialisation.
118             Override this method if required.
119              
120             =cut
121              
122             sub init {
123 3     3 1 177 my $self = shift;
124 3         6 my $params = shift;
125            
126            
127            
128 3         8 return 1;
129            
130             }
131              
132              
133             =head1 Subclass method stubs
134              
135             The following methods are in this parent class (but only implemented as stubs) in order to define a
136             common interface for all VoiceXML::Client::DeviceHandle subclasses.
137              
138             These methods are actually heavily based on the Modem::Vgetty package methods and the interface should
139             be considered tentative and expected to change as new devices are added (eg a SIP voice over IP interface
140             would be nice).
141              
142             =cut
143              
144              
145             sub connect {
146 0     0 0   my $self = shift;
147 0           my $params = shift;
148            
149 0 0         print STDERR "VoiceXML::Client::DeviceHandle::connect() Call to parent class stub - please implement in subclass.\n"
150             if ($VoiceXML::Client::Debug);
151            
152 0           return 1;
153             }
154              
155              
156             sub disconnect {
157 0     0 0   my $self = shift;
158 0           my $params = shift;
159            
160 0 0         print STDERR "VoiceXML::Client::DeviceHandle::disconnect() Call to parent class stub - please implement in subclass.\n"
161             if ($VoiceXML::Client::Debug);
162            
163 0           return 1;
164             }
165              
166              
167              
168             =head2 beep FREQUENCY LENGTH
169              
170             Sends a beep through the chosen device using given frequency (HZ) and length (in miliseconds). Returns a defined
171             and true value on success.
172              
173             =cut
174              
175             sub beep {
176 0     0 1   my $self = shift;
177 0           my $frequency = shift;
178 0           my $length = shift;
179            
180 0           print STDERR "VoiceXML::Client::DeviceHandle::beep($frequency, $length) Call to parent class stub - please implement in subclass.\n";
181            
182 0           return 1;
183             }
184              
185              
186              
187             =head2 dial DESTINATION
188              
189             Connects to destination. Returns defined & true on success.
190              
191             =cut
192              
193             sub dial {
194 0     0 1   my $self = shift;
195 0           my $destination = shift;
196            
197 0           print STDERR "VoiceXML::Client::DeviceHandle::dial($destination) Call to parent class stub - please implement in subclass.\n";
198            
199 0           return 1;
200             }
201              
202              
203             =head2 play PLAYPARAM
204              
205             plays a sound (file, text-to-speech, whatever is appropriate) base on PLAYPARAM. May or may not block during
206             play depending on device implementation. Returns true on success.
207              
208             =cut
209              
210             sub play {
211 0     0 1   my $self = shift;
212 0           my $playthis = shift;
213 0           my $type = shift;
214            
215            
216 0           print STDERR "VoiceXML::Client::DeviceHandle::play($playthis) Call to parent class stub - please implement in subclass.\n";
217            
218 0           return 1;
219             }
220              
221              
222             =head2 record TOFILE
223              
224             Records input from user to device to file TOFILE. Returns true on success.
225              
226             =cut
227              
228             sub record {
229 0     0 1   my $self = shift;
230 0           my $tofile = shift;
231            
232            
233 0           print STDERR "VoiceXML::Client::DeviceHandle::record($tofile) Call to parent class stub - please implement in subclass.\n";
234            
235 0           return 1;
236             }
237              
238              
239             =head2 wait TIME
240              
241             Simply waits for TIME seconds. Device should accept/queue user input
242             during interval.
243              
244             =cut
245              
246             sub wait {
247 0     0 1   my $self = shift;
248 0           my $time = shift;
249            
250            
251 0           print STDERR "VoiceXML::Client::DeviceHandle::wait($time) Call to parent class stub - please implement in subclass.\n";
252            
253 0           return 1;
254             }
255              
256              
257             =head2 waitFor STATE
258              
259             Waits until STATE is reached/returned by device. Device should accept/queue user input
260             during interval.
261              
262             =cut
263              
264             sub waitFor {
265 0     0 1   my $self = shift;
266 0           my $state = shift;
267            
268 0           print STDERR "VoiceXML::Client::DeviceHandle::waitFor($state) Call to parent class stub - please implement in subclass.\n";
269            
270 0           return 1;
271             }
272              
273             =head2 stop
274              
275             Immediately stop any current activity (wait, play, record, etc.).
276              
277             =cut
278             sub stop {
279 0     0 1   my $self = shift;
280            
281            
282 0           print STDERR "VoiceXML::Client::DeviceHandle::stop() Call to parent class stub - please implement in subclass.\n";
283            
284 0           return 1;
285             }
286              
287             =head2 blocking_play PLAYTHIS
288              
289             play PLAYTHIS and return only when done.
290              
291             =cut
292              
293             sub blockingPlay {
294 0     0 0   my $self = shift;
295 0           my $playthis = shift;
296 0           my $type = shift;
297            
298            
299 0           print STDERR "VoiceXML::Client::DeviceHandle::blocking_play($playthis) Call to parent class stub - please implement in subclass.\n";
300            
301 0           return 1;
302             }
303              
304              
305             =head2 inputMode [MODE]
306              
307             Returns the current input mode (single- or multi- digit currently supported), optionally setting to
308             MODE, if passed - use the %VoiceXML::Client::DeviceHandle::InputMode hash for valid MODE values.
309              
310             =cut
311              
312             sub inputMode {
313 0     0 1   my $self = shift;
314 0           my $setTo = shift;
315            
316 0 0         if (defined $setTo)
317             {
318 0           $self->{'inputmode'} = $setTo;
319             }
320            
321 0           return $self->{'inputmode'};
322             }
323              
324             =head2 readnum PLAYTHIS TIMEOUT [REPEATTIMES]
325              
326             Plays the PLAYTHIS and then waits for the sequence of the digit input finished. If no are entered within TIMEOUT
327             seconds, it re-plays the message again. It returns failure (undefined value) if no digits are entered after the message
328             has been played REPEATTIMES (defaults to 3) times.
329              
330              
331             It returns a string (a sequence of DTMF tones 0-9,A-D and `*') without the final stop key (normally '#').
332              
333              
334             =cut
335              
336              
337             sub readnum {
338 0     0 1   my $self = shift;
339 0           my $playthis = shift;
340 0           my $timeout = shift;
341 0   0       my $repeatTimes = shift || 3;
342            
343            
344 0           print STDERR "VoiceXML::Client::DeviceHandle::beep() Call to parent class stub - please implement in subclass.\n";
345            
346 0           return 1;
347             }
348              
349              
350              
351              
352             =head2 validDataFormats
353              
354             Returns an array ref of valid data formats (eg 'rmd', 'wav', 'au') the device will accept.
355              
356             =cut
357              
358             sub validDataFormats {
359 0     0 1   my $self = shift;
360            
361 0           print STDERR "VoiceXML::Client::DeviceHandle::validDataFormats() Call to parent class stub - please implement in subclass.\n";
362            
363 0           return undef;
364             }
365              
366              
367              
368             sub receiveImage {
369 0     0 0   my $self = shift;
370            
371 0           print STDERR "VoiceXML::Client::DeviceHandle::receiveImage() Call to parent class stub - please implement in subclass.\n";
372            
373 0           return 1;
374             }
375              
376              
377             # Not sure what to do with this method... how do you support faxes while abstracting the modem voice device??
378             sub sendImage {
379 0     0 0   my $self = shift;
380 0           my $file = shift;
381            
382 0           print STDERR "VoiceXML::Client::DeviceHandle::sendImage() Call to parent class stub - please implement in subclass.\n";
383            
384 0           return 1;
385             }
386              
387              
388             sub notifyCallbacksOfInputReceived {
389 0     0 0   my $input = shift;
390            
391 0           while (my ($name, $dets) = each %{$ReadnumGlobals{$$}{'inputReceivedCallbacks'}})
  0            
392             {
393 0 0         VoiceXML::Client::Util::log_msg("Notifying $name of input received") if ($VoiceXML::Client::Debug);
394 0           my $obj = $dets->{'object'};
395 0           my $meth = $dets->{'method'};
396            
397 0           $obj->$meth($ReadnumGlobals{$$}{'device_obj'}, $input);
398             }
399            
400 0           return;
401             }
402              
403             sub registerInputReceivedCallback {
404 0     0 0   my $self = shift;
405 0   0       my $name = shift || return;
406 0           my $object = shift;
407 0           my $method = shift;
408            
409 0 0 0       unless ($object && $object->can($method))
410             {
411 0           VoiceXML::Client::Util::log_msg("Trying to register $method on $object but object can't do that");
412 0           return;
413             }
414            
415 0 0         VoiceXML::Client::Util::log_msg("Registering $method on $object for input received callback") if ($VoiceXML::Client::Debug);
416            
417 0           $ReadnumGlobals{$$}{'inputReceivedCallbacks'}->{$name} = {
418             'object' => $object,
419             'method' => $method
420             };
421 0           return 1;
422             }
423              
424             sub deleteInputReceivedCallback {
425 0     0 0   my $self = shift;
426 0   0       my $name = shift || return;
427            
428 0 0         delete $ReadnumGlobals{$$}{'inputReceivedCallbacks'}->{$name} if (exists $ReadnumGlobals{$$}{'inputReceivedCallbacks'}->{$name});
429            
430 0           return;
431             }
432              
433              
434              
435             sub resetReadnumGlobalNumberCache {
436 0   0 0 0   my $cacheID = shift || return;
437            
438 0           $ReadnumGlobals{$cacheID}{'readnum_number'} = '';
439            
440 0           return;
441             }
442              
443             sub appendPendingInput {
444 0     0 0   my $self = shift;
445 0           my $input = shift;
446            
447 0 0         return unless defined ($input);
448            
449 0 0         $ReadnumGlobals{$$}{'readnum_number'} = '' unless (defined $ReadnumGlobals{$$}{'readnum_number'});
450 0           $ReadnumGlobals{$$}{'readnum_number'} .= $input;
451            
452 0           return $input;
453             }
454              
455            
456             sub pendingInputLength {
457 0     0 0   my $self = shift;
458            
459            
460 0           my $readnumid = $$; # So it's safe to have multiple devices...
461            
462 0 0         my $retnum = defined $ReadnumGlobals{$readnumid}{'readnum_number'} ?
463             $ReadnumGlobals{$readnumid}{'readnum_number'} : '';
464            
465 0 0         VoiceXML::Client::Util::log_msg("pendingInputLength() called returning length of '$retnum'") if ($VoiceXML::Client::Debug > 1);
466            
467 0           return length($retnum);
468             }
469              
470              
471             sub fetchPendingInput {
472 0     0 0   my $self = shift;
473            
474            
475 0           my $readnumid = $$; # So it's safe to have multiple devices...
476            
477 0 0         my $retnum = defined $ReadnumGlobals{$readnumid}{'readnum_number'} ?
478             $ReadnumGlobals{$readnumid}{'readnum_number'} : '';
479            
480 0           resetReadnumGlobalNumberCache($readnumid);
481            
482 0           return $retnum;
483             }
484              
485              
486             1;