File Coverage

blib/lib/Device/Modem.pm
Criterion Covered Total %
statement 19 345 5.5
branch 1 128 0.7
condition 0 92 0.0
subroutine 5 34 14.7
pod 24 27 88.8
total 49 626 7.8


line stmt bran cond sub pod time code
1             # Device::Modem - a Perl class to interface generic modems (AT-compliant)
2             # Copyright (C) 2002-2020 Cosimo Streppone, cosimo@cpan.org
3             #
4             # This program is free software; you can redistribute it and/or
5             # modify it under the same terms as Perl itself.
6             #
7             # This program is distributed in the hope that it will be useful,
8             # but WITHOUT ANY WARRANTY; without even the implied warranty of
9             # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10             # Perl licensing terms for details.
11              
12             package Device::Modem;
13             our $VERSION = '1.59';
14             $VERSION = eval $VERSION;
15              
16             BEGIN {
17              
18 2 50   2   71810 if( index($^O, 'Win') >= 0 ) { # MSWin32 (and not darwin, cygwin, ...)
19              
20 0         0 require Win32::SerialPort;
21 0         0 Win32::SerialPort->import;
22              
23             # Import line status constants from Win32::SerialPort module
24 0         0 *Device::Modem::MS_CTS_ON = *Win32::SerialPort::MS_CTS_ON;
25 0         0 *Device::Modem::MS_DSR_ON = *Win32::SerialPort::MS_DSR_ON;
26 0         0 *Device::Modem::MS_RING_ON = *Win32::SerialPort::MS_RING_ON;
27 0         0 *Device::Modem::MS_RLSD_ON = *Win32::SerialPort::MS_RLSD_ON;
28              
29             } else {
30              
31 2         1612 require Device::SerialPort;
32 2         65525 Device::SerialPort->import;
33              
34             # Import line status constants from Device::SerialPort module
35 2         12 *Device::Modem::MS_CTS_ON = *Device::SerialPort::MS_CTS_ON;
36 2         7 *Device::Modem::MS_DSR_ON = *Device::SerialPort::MS_DSR_ON;
37 2         5 *Device::Modem::MS_RING_ON = *Device::SerialPort::MS_RING_ON;
38 2         71 *Device::Modem::MS_RLSD_ON = *Device::SerialPort::MS_RLSD_ON;
39              
40             }
41             }
42              
43 2     2   15 use strict;
  2         4  
  2         40  
44 2     2   9 use Carp ();
  2         4  
  2         62  
45              
46             # Constants definition
47 2     2   12 use constant CTRL_Z => chr(26);
  2         4  
  2         229  
48 2     2   13 use constant CR => "\r";
  2         4  
  2         8611  
49              
50             # Connection defaults
51             $Device::Modem::DEFAULT_PORT = index($^O, 'Win') >= 0 ? 'COM1' : '/dev/modem';
52             $Device::Modem::DEFAULT_INIT_STRING = 'S7=45 S0=0 L1 V1 X4 &c1 E1 Q0';
53             $Device::Modem::BAUDRATE = 19200;
54             $Device::Modem::DATABITS = 8;
55             $Device::Modem::STOPBITS = 1;
56             $Device::Modem::HANDSHAKE= 'none';
57             $Device::Modem::PARITY = 'none';
58             $Device::Modem::TIMEOUT = 500; # milliseconds
59             $Device::Modem::READCHARS= 130;
60             $Device::Modem::WAITCMD = 200; # milliseconds
61              
62             # Setup text and numerical response codes
63             @Device::Modem::RESPONSE = ( 'OK', undef, 'RING', 'NO CARRIER', 'ERROR', undef, 'NO DIALTONE', 'BUSY' );
64             $Device::Modem::STD_RESPONSE = qr/^(OK|ERROR|COMMAND NOT SUPPORT)$/m;
65              
66             #%Device::Modem::RESPONSE = (
67             # 'OK' => 'Command executed without errors',
68             # 'RING' => 'Detected phone ring',
69             # 'NO CARRIER' => 'Link not established or disconnected',
70             # 'ERROR' => 'Invalid command or command line too long',
71             # 'NO DIALTONE' => 'No dial tone, dialing not possible or wrong mode',
72             # 'BUSY' => 'Remote terminal busy'
73             #);
74              
75             # object constructor (prepare only object)
76             sub new {
77 0     0 1   my($proto,%aOpt) = @_; # Get reference to object
78             # Options of object
79 0   0       my $class = ref($proto) || $proto; # Get reference to class
80              
81 0           $aOpt{'ostype'} = $^O; # Store OSTYPE in object
82 0 0         $aOpt{'ostype'} = 'windoze' if index( $aOpt{'ostype'}, 'Win' ) >= 0;
83              
84             # Initialize flags array
85 0           $aOpt{'flags'} = {};
86              
87             # Start as not connected
88 0           $aOpt{'CONNECTED'} = 0;
89              
90 0   0       $aOpt{'port'} ||= $Device::Modem::DEFAULT_PORT;
91              
92             # Instance log object
93 0   0       $aOpt{'log'} ||= 'file';
94              
95             # Force logging to file if this is windoze and user requested syslog mechanism
96 0 0 0       $aOpt{'log'} = 'file' if( $aOpt{'ostype'} eq 'windoze' && $aOpt{'log'} =~ /syslog/i );
97 0   0       $aOpt{'loglevel'} ||= 'warning';
98              
99 0 0         if( ! ref $aOpt{'log'} ) {
100 0           my($method, @options) = split ',', delete $aOpt{'log'};
101 0           my $logclass = 'Device/Modem/Log/'.ucfirst(lc $method).'.pm';
102 0           my $package = 'Device::Modem::Log::'.ucfirst lc $method;
103 0           eval { require $logclass; };
  0            
104 0 0         unless($@) {
105 0           $aOpt{'_log'} = $package->new( $class, @options );
106             } else {
107 0           print STDERR "Failed to require Log package: $@\n";
108             }
109             } else {
110              
111             # User passed an already instanced log object
112 0           $aOpt{'_log'} = $aOpt{'log'};
113             }
114              
115 0 0 0       if( ref $aOpt{'_log'} && $aOpt{'_log'}->can('loglevel') ) {
116 0           $aOpt{'_log'}->loglevel($aOpt{'loglevel'});
117             }
118              
119 0           bless \%aOpt, $class; # Instance $class object
120             }
121              
122             sub attention {
123 0     0 1   my $self = shift;
124 0           $self->log->write('info', 'sending attention sequence...');
125              
126             # Send attention sequence
127 0           $self->atsend('+++');
128              
129             # Wait for response
130 0           $self->answer();
131             }
132              
133             sub dial {
134 0     0 1   my($self, $number, $timeout, $mode) = @_;
135 0           my $ok = 0;
136              
137             # Default timeout in seconds
138 0   0       $timeout ||= 30;
139              
140             # Default is data calls
141 0 0 0       if (! defined $mode) {
    0          
142 0           $mode = 'DATA';
143             }
144             # Numbers with ';' mean voice calls
145             elsif ($mode =~ m{VOICE}i || $number =~ m{;}) {
146 0           $mode = 'VOICE';
147             }
148             # Invalid input, or explicit 'DATA' call
149             else {
150 0           $mode = 'DATA';
151             }
152              
153             # Check if we have already dialed some number...
154 0 0         if ($self->flag('CARRIER')) {
155 0           $self->log->write( 'warning', 'line is already connected, ignoring dial()' );
156 0           return;
157             }
158              
159             # Check if no number supplied
160 0 0         if (! defined $number) {
161             #
162             # XXX Here we could enable ATDL command (dial last number)
163             #
164 0           $self->log->write( 'warning', 'cannot dial without a number!' );
165 0           return;
166             }
167              
168             # Remove all non number chars plus some others allowed
169             # Thanks to Pierre Hilson for the `#' (UMTS)
170             # and to Marek Jaros for the `;' (voice calls)
171 0           $number =~ s{[^0-9,\(\)\*\-#;\sp]}{}g;
172              
173 0           my $suffix = '';
174 0 0         if ($mode eq 'VOICE') {
175 0           $self->log->write('info', 'trying to make a voice call');
176 0           $suffix = ';';
177             }
178              
179             # Dial number and wait for response
180 0 0         if( length $number == 1 ) {
181 0           $self->log->write('info', 'dialing address book number ['.$number.']' );
182              
183 0           $self->atsend( 'ATDS' . $number . $suffix . CR );
184             } else {
185 0           $self->log->write('info', 'dialing number ['.$number.']' );
186 0           $self->atsend( 'ATDT' . $number . $suffix . CR );
187             }
188              
189             # XXX Check response times here (timeout!)
190 0           my $ans = $self->answer( qr/[A-Z]/, $timeout * 1000 );
191              
192 0 0 0       if( (index($ans,'CONNECT') > -1) || (index($ans,'RING') > -1) ) {
193 0           $ok = 1;
194             }
195              
196             # Turn on/off `CARRIER' flag
197 0           $self->flag('CARRIER', $ok);
198              
199 0           $self->log->write('info', 'dialing result = '.$ok);
200 0 0         return wantarray ? ($ok, $ans) : $ok;
201             }
202              
203             # Enable/disable local echo of commands (enabling echo can cause everything else to fail, I think)
204             sub echo {
205 0     0 1   my($self, $lEnable) = @_;
206              
207 0 0         $self->log->write( 'info', ( $lEnable ? 'enabling' : 'disabling' ) . ' echo' );
208 0 0         $self->atsend( ($lEnable ? 'ATE1' : 'ATE0') . CR );
209              
210 0           $self->answer($Device::Modem::STD_RESPONSE);
211             }
212              
213             # Terminate current call (XXX not tested)
214             sub hangup {
215 0     0 1   my $self = shift;
216              
217 0           $self->log->write('info', 'hanging up...');
218 0           $self->atsend( 'ATH0' . CR );
219 0           my $ok = $self->answer($Device::Modem::STD_RESPONSE);
220 0 0         unless ($ok) {
221 0           $self->attention();
222 0           $self->atsend( 'ATH0' . CR );
223 0           $self->answer($Device::Modem::STD_RESPONSE, 5000);
224             }
225 0           $self->_reset_flags();
226             }
227              
228             # Checks if modem is enabled (for now, it works ok for modem OFF/ON case)
229             sub is_active {
230 0     0 1   my $self = shift;
231 0           my $lOk;
232              
233 0   0       $self->log->write('info', 'testing modem activity on port ' . ($self->options->{'port'} || '') );
234              
235             # Modem is active if already connected to a line
236 0 0         if( $self->flag('CARRIER') ) {
237              
238 0           $self->log->write('info', 'carrier is '.$self->flag('CARRIER').', modem is connected, it should be active');
239 0           $lOk = 1;
240              
241             } else {
242              
243             # XXX Old mode to test modem ...
244             # Try sending an echo enable|disable command
245             #$self->attention();
246             #$self->verbose(0);
247             #$lOk = $self->verbose(1);
248              
249             # If DSR signal is on, modem is active
250 0           my %sig = $self->status();
251 0           $lOk = $sig{DSR};
252 0           undef %sig;
253              
254             # If we have no success, try to reset
255 0 0         if( ! $lOk ) {
256 0           $self->log->write('warning', 'modem not responding... trying to reset');
257 0           $lOk = $self->reset();
258             }
259              
260             }
261              
262 0           $self->log->write('info', 'modem reset result = '.$lOk);
263              
264 0           return $lOk;
265             }
266              
267             # Take modem off hook, prepare to dial
268             sub offhook {
269 0     0 1   my $self = shift;
270              
271 0           $self->log->write('info', 'taking off hook');
272 0           $self->atsend( 'ATH1' . CR );
273              
274 0           $self->flag('OFFHOOK', 1);
275              
276 0           return 1;
277             }
278              
279             # Get/Set S* registers value: S_register( number [, new_value] )
280             # returns undef on failure ( zero is a good value )
281             sub S_register {
282 0     0 1   my $self = shift;
283 0           my $register = shift;
284 0           my $value = 0;
285              
286 0 0         return unless $register;
287              
288 0           my $ok;
289              
290             # If `new_value' supplied, we want to update value of this register
291 0 0         if( @_ ) {
292              
293 0           my $new_value = shift;
294 0           $new_value =~ s|\D||g;
295 0           $self->log->write('info', 'storing value ['.$new_value.'] into register S'.$register);
296 0           $self->atsend( sprintf( 'AT S%02d=%d' . CR, $register, $new_value ) );
297              
298 0 0         $value = ( index( $self->answer(), 'OK' ) != -1 ) ? $new_value : undef;
299              
300             } else {
301              
302 0           $self->atsend( sprintf( 'AT S%d?' . CR, $register ) );
303 0           ($ok, $value) = $self->parse_answer();
304              
305 0 0         if( index($ok, 'OK') != -1 ) {
306 0           $self->log->write('info', 'value of S'.$register.' register seems to be ['.$value.']');
307             } else {
308 0           $value = undef;
309 0           $self->log->write('err', 'error reading value of S'.$register.' register');
310             }
311              
312             }
313              
314             # Return updated value of register
315 0           $self->log->write('info', 'S'.$register.' = '.$value);
316              
317 0           return $value;
318             }
319              
320             # Repeat the last commands (this comes gratis with `A/' at-command)
321             sub repeat {
322 0     0 1   my $self = shift;
323              
324 0           $self->log->write('info', 'repeating last command' );
325 0           $self->atsend( 'A/' . CR );
326              
327 0           $self->answer();
328             }
329              
330             # Complete modem reset
331             sub reset {
332 0     0 1   my $self = shift;
333              
334 0           $self->log->write('warning', 'resetting modem on '.$self->{'port'} );
335 0           $self->hangup();
336 0           my $result = $self->send_init_string();
337 0           $self->_reset_flags();
338 0           return $result;
339             }
340              
341             # Return an hash with the status of main modem signals
342             sub status {
343 0     0 1   my $self = shift;
344 0           $self->log->write('info', 'getting modem line status on '.$self->{'port'});
345              
346             # This also relies on Device::SerialPort
347 0           my $status = $self->port->modemlines();
348              
349             # See top of module for these constants, exported by (Win32|Device)::SerialPort
350 0           my %signal = (
351             CTS => $status & Device::Modem::MS_CTS_ON,
352             DSR => $status & Device::Modem::MS_DSR_ON,
353             RING => $status & Device::Modem::MS_RING_ON,
354             RLSD => $status & Device::Modem::MS_RLSD_ON
355             );
356              
357 0           $self->log->write('info', 'modem on '.$self->{'port'}.' status is ['.$status.']');
358 0           $self->log->write('info', "CTS=$signal{CTS} DSR=$signal{DSR} RING=$signal{RING} RLSD=$signal{RLSD}");
359              
360 0           return %signal;
361             }
362              
363             # Of little use here, but nice to have it
364             # restore_factory_settings( profile )
365             # profile can be 0 or 1
366             sub restore_factory_settings {
367 0     0 1   my $self = shift;
368 0           my $profile = shift;
369 0 0         $profile = 0 unless defined $profile;
370              
371 0           $self->log->write('warning', 'restoring factory settings '.$profile.' on '.$self->{'port'} );
372 0           $self->atsend( 'AT&F'.$profile . CR);
373              
374 0           $self->answer($Device::Modem::STD_RESPONSE);
375             }
376              
377             # Store telephone number in modem's internal address book, to dial later
378             # store_number( position, number )
379             sub store_number {
380 0     0 1   my( $self, $position, $number ) = @_;
381 0           my $ok = 0;
382              
383             # Check parameters
384 0 0 0       unless( defined($position) && $number ) {
385 0           $self->log->write('warning', 'store_number() called with wrong parameters');
386 0           return $ok;
387             }
388              
389 0           $self->log->write('info', 'storing number ['.$number.'] into memory ['.$position.']');
390              
391             # Remove all non-numerical chars from position and number
392 0           $position =~ s/\D//g;
393 0           $number =~ s/[^0-9,]//g;
394              
395 0           $self->atsend( sprintf( 'AT &Z%d=%s' . CR, $position, $number ) );
396              
397 0 0         if( index( $self->answer(), 'OK' ) != -1 ) {
398 0           $self->log->write('info', 'stored number ['.$number.'] into memory ['.$position.']');
399 0           $ok = 1;
400             } else {
401 0           $self->log->write('warning', 'error storing number ['.$number.'] into memory ['.$position.']');
402 0           $ok = 0;
403             }
404              
405 0           return $ok;
406             }
407              
408             # Enable/disable verbose response messages against numerical response messages
409             # XXX I need to manage also numerical values...
410             sub verbose {
411 0     0 1   my($self, $lEnable) = @_;
412              
413 0 0         $self->log->write( 'info', ( $lEnable ? 'enabling' : 'disabling' ) . ' verbose messages' );
414 0 0         $self->atsend( ($lEnable ? 'ATQ0V1' : 'ATQ0V0') . CR );
415              
416 0           $self->answer($Device::Modem::STD_RESPONSE);
417             }
418              
419             sub wait {
420 0     0 1   my( $self, $msec ) = @_;
421              
422 0           $self->log->write('debug', 'waiting for '.$msec.' msecs');
423              
424             # Perhaps Time::HiRes here is not so useful, since I tested `select()' system call also on Windows
425 0           select( undef, undef, undef, $msec / 1000 );
426 0           return 1;
427              
428             }
429              
430             # Set a named flag. Flags are now: OFFHOOK, CARRIER
431             sub flag {
432 0     0 0   my $self = shift;
433 0           my $cFlag = uc shift;
434              
435 0 0         $self->{'_flags'}->{$cFlag} = shift() if @_;
436              
437 0           $self->{'_flags'}->{$cFlag};
438             }
439              
440             # reset internal flags that tell the status of modem (XXX to be extended)
441             sub _reset_flags {
442 0     0     my $self = shift();
443              
444 0           map { $self->flag($_, 0) }
  0            
445             'OFFHOOK', 'CARRIER';
446             }
447              
448             # initialize modem with some basic commands (XXX &C0)
449             # send_init_string( [my_init_string] )
450             # my_init_string goes without 'AT' prefix
451             sub send_init_string {
452 0     0 1   my($self, $cInit) = @_;
453 0 0         $cInit = $self->options->{'init_string'} unless defined $cInit;
454             # If no Init string then do nothing!
455 0 0         if ($cInit) {
456 0           $self->attention();
457 0           $self->atsend('AT '.$cInit. CR );
458 0           return $self->answer($Device::Modem::STD_RESPONSE);
459             }
460             }
461              
462             # returns log object reference or nothing if it is not defined
463             sub log {
464 0     0 1   my $me = shift;
465 0 0         if( ref $me->{'_log'} ) {
466 0           return $me->{'_log'};
467             } else {
468 0           return {};
469             }
470             }
471              
472             # instances (Device|Win32)::SerialPort object and initializes communications
473             sub connect {
474 0     0 1   my $me = shift();
475              
476 0           my %aOpt = ();
477 0 0         if( @_ ) {
478 0           %aOpt = @_;
479             }
480              
481 0           my $lOk = 0;
482              
483             # Set default values if missing
484 0   0       $aOpt{'baudrate'} ||= $Device::Modem::BAUDRATE;
485 0   0       $aOpt{'databits'} ||= $Device::Modem::DATABITS;
486 0   0       $aOpt{'parity'} ||= $Device::Modem::PARITY;
487 0   0       $aOpt{'stopbits'} ||= $Device::Modem::STOPBITS;
488 0   0       $aOpt{'handshake'}||= $Device::Modem::HANDSHAKE;
489 0   0       $aOpt{'max_reset_iter'} ||= 0;
490              
491             # Store communication options in object
492 0           $me->{'_comm_options'} = \%aOpt;
493              
494             # Connect on serial (use different mod for win32)
495 0 0         if( $me->ostype eq 'windoze' ) {
496 0           $me->port( Win32::SerialPort->new($me->{'port'}) );
497             } else {
498 0           $me->port( Device::SerialPort->new($me->{'port'}) );
499             }
500              
501             # Check connection
502 0 0         unless( ref $me->port ) {
503 0           $me->log->write( 'err', '*FAILED* connect on '.$me->{'port'} );
504 0           return $lOk;
505             }
506              
507             # Set communication options
508 0           my $oPort = $me->port;
509 0           $oPort -> baudrate ( $me->options->{'baudrate'} );
510 0           $oPort -> databits ( $me->options->{'databits'} );
511 0           $oPort -> stopbits ( $me->options->{'stopbits'} );
512 0           $oPort -> parity ( $me->options->{'parity'} );
513 0           $oPort -> handshake( $me->options->{'handshake'} );
514              
515             # Non configurable options
516 0           $oPort -> buffers ( 10000, 10000 );
517 0           $oPort -> read_const_time ( 20 ); # was 500
518 0           $oPort -> read_char_time ( 0 );
519              
520             # read_interval() seems to be unsupported on Device::SerialPort,
521             # while allowed on Win32::SerialPort...
522 0 0         if( $oPort->can('read_interval') )
523             {
524 0           $oPort->read_interval( 20 );
525             }
526              
527 0           $oPort -> are_match ( 'OK' );
528 0           $oPort -> lookclear;
529              
530 0 0         unless ( $oPort -> write_settings ) {
531 0           $me->log->write('err', '*FAILED* write_settings on '.$me->{'port'} );
532 0           return $lOk;
533             }
534 0           $oPort -> purge_all;
535              
536             # Get the modems attention
537             # Send multiple reset commands looking for a sensible response.
538             # A small number of modems need time to settle down and start responding to the serial port
539 0           my $iter = 0;
540 0           my $ok = 0;
541 0           my $blank = 0;
542 0   0       while ( ($iter < $aOpt{'max_reset_iter'}) && ($ok < 2) && ($blank < 3) ) {
      0        
543 0           $me->atsend('AT E0'. CR );
544 0           my $rslt = $me->answer($Device::Modem::STD_RESPONSE, 1500);
545             # print "Res: $rslt \r\n";
546 0           $iter+=1;
547 0 0 0       if ($rslt && $rslt =~ /^OK/) {
548 0           $ok+=1;
549             } else {
550 0           $ok=0;
551             }
552 0 0         if (!$rslt) {
553 0           $blank++;
554             } else {
555 0           $blank=0;
556             }
557             }
558 0 0         if ($aOpt{'max_reset_iter'}) {
559 0           $me->log->write('debug', "DEBUG CONNECT: $iter : $ok : $blank\n"); # DEBUG
560             }
561 0           $me-> log -> write('info', 'sending init string...' );
562              
563             # Set default initialization string if none supplied
564             my $init_string = defined $me->options->{'init_string'}
565 0 0         ? $me->options->{'init_string'}
566             : $Device::Modem::DEFAULT_INIT_STRING;
567              
568 0   0       my $init_response = $me->send_init_string($init_string) || '';
569 0           $me-> log -> write('debug', "init response: $init_response\n"); # DEBUG
570 0           $me-> _reset_flags();
571              
572             # Disable local echo
573 0           $me-> echo(0);
574              
575 0           $me-> log -> write('info', 'Ok connected' );
576 0           $me-> {'CONNECTED'} = 1;
577              
578             }
579              
580             # $^O is stored into object
581             sub ostype {
582 0     0 0   my $self = shift;
583 0           $self->{'ostype'};
584             }
585              
586             # returns Device::SerialPort reference to hash options
587             sub options {
588 0     0 0   my $self = shift();
589             @_ ? $self->{'_comm_options'} = shift()
590 0 0         : $self->{'_comm_options'};
591             }
592              
593             # returns Device::SerialPort object handle
594             sub port {
595 0     0 1   my $self = shift;
596              
597 0 0         if (@_) {
598 0           return ($self->{'_comm_object'} = shift);
599             }
600              
601 0           my $port_obj = $self->{'_comm_object'};
602              
603             # Maybe the port was disconnected?
604 0 0 0       if (defined $self->{'CONNECTED'} &&
      0        
      0        
605             $self->{'CONNECTED'} == 1 && # We were connected
606             (! defined $port_obj || ! $port_obj)) { # Now we aren't anymore
607              
608             # Avoid recursion on ourselves
609 0           $self->{'CONNECTED'} = 0;
610              
611             # Try to reconnect if possible
612 0           my $connect_options = $self->options;
613              
614             # No connect options probably because we didn't ever connect
615 0 0         if (! $connect_options) {
616 0           Carp::croak("Not connected");
617             }
618              
619 0           $self->connect(%{ $connect_options });
  0            
620 0           $port_obj = $self->{'_comm_object'};
621             }
622              
623             # Still not connected? bail out
624 0 0 0       if (! defined $port_obj || ! $port_obj) {
625 0           Carp::croak("Not connected");
626             }
627              
628 0           return $port_obj;
629             }
630              
631             # disconnect serial port
632             sub disconnect {
633 0     0 1   my $me = shift;
634 0           $me->port->close();
635 0           $me->log->write('info', 'Disconnected from '.$me->{'port'} );
636             }
637              
638             # Send AT command to device on serial port (command must include CR for now)
639             sub atsend {
640 0     0 1   my( $me, $msg ) = @_;
641 0           my $cnt = 0;
642              
643             # Write message on port
644 0           $me->port->purge_all();
645 0           $cnt = $me->port->write($msg);
646              
647 0           my $lbuf=length($msg);
648 0           my $ret;
649              
650 0           while ($cnt < $lbuf)
651             {
652 0           $ret = $me->port->write(substr($msg, $cnt));
653 0           $me->write_drain();
654 0 0         last unless defined $ret;
655 0           $cnt += $ret;
656             }
657              
658 0           $me->log->write('debug', 'atsend: wrote '.$cnt.'/'.length($msg).' chars');
659              
660             # If wrote all chars of `msg', we are successful
661 0           return $cnt == length $msg;
662             }
663              
664             # Call write_drain() if platform allows to (no call for Win32)
665             sub write_drain
666             {
667 0     0 1   my $me = shift;
668              
669             # No write_drain() call for win32 systems
670 0 0         return if $me->ostype eq 'windoze';
671              
672             # No write_drain() if no port object available
673 0           my $port = $me->port;
674 0 0         return unless $port;
675              
676 0           return $port->write_drain();
677             }
678              
679             # answer() takes strings from the device until a pattern
680             # is encountered or a timeout happens.
681             sub _answer {
682 0     0     my $me = shift;
683 0           my($expect, $timeout) = @_;
684 0 0         $expect = $Device::Modem::STD_RESPONSE if (! defined($expect));
685 0 0         $timeout = $Device::Modem::TIMEOUT if (! defined($timeout));
686              
687             # If we expect something, we must first match against serial input
688 0   0       my $done = (defined $expect and $expect ne '');
689              
690 0 0 0       $me->log->write('debug', 'answer: expecting ['.($expect||'').']'.($timeout ? ' or '.($timeout/1000).' seconds timeout' : '' ) );
691              
692             # Main read cycle
693 0           my $cycles = 0;
694 0           my $idle_cycles = 0;
695 0           my $answer;
696 0           my $start_time = time();
697 0           my $end_time = 0;
698              
699             # If timeout was defined, check max time (timeout is in milliseconds)
700 0   0       $me->log->write('debug', 'answer: timeout value is '.($timeout||'undef'));
701              
702 0 0 0       if( defined $timeout && $timeout > 0 ) {
703 0           $end_time = $start_time + ($timeout / 1000);
704 0 0         $end_time++ if $end_time == $start_time;
705 0           $me->log->write( debug => 'answer: end time set to '.$end_time );
706             }
707              
708 0           do {
709 0           my ($what, $howmany);
710 0           $what = $me->port->read(1) . $me->port->input;
711 0           $howmany = length($what);
712              
713             # Timeout count incremented only on empty readings
714 0 0 0       if( defined $what && $howmany > 0 ) {
    0          
715              
716             # Add received chars to answer string
717 0           $answer .= $what;
718              
719             # Check if buffer matches "expect string"
720 0 0         if( defined $expect ) {
721 0           my $copy = $answer;
722 0           $copy =~ s/\r(\n)?/\n/g; # Convert line endings from "\r" or "\r\n" to "\n"
723 0 0 0       $done = ( defined $copy && $copy =~ $expect ) ? 1 : 0;
724 0 0         $me->log->write( debug => 'answer: matched expect: '.$expect ) if ($done);
725             }
726              
727             # Check if we reached max time for timeout (only if end_time is defined)
728             } elsif( $end_time > 0 ) {
729              
730 0 0         $done = (time >= $end_time) ? 1 : 0;
731              
732             # Read last chars in read queue
733 0 0         if( $done )
734             {
735 0           $me->log->write('info', 'reached timeout max wait without response');
736             }
737              
738             # Else we have done
739             } else {
740              
741 0           $done = 1;
742             }
743              
744 0           $me->log->write('debug', 'done='.$done.' end='.$end_time.' now='.time().' start='.$start_time );
745              
746             } while (not $done);
747              
748 0   0       $me->log->write('info', 'answer: read ['.($answer||'').']' );
749              
750             # Flush receive and trasmit buffers
751 0           $me->port->purge_all;
752              
753 0           return $answer;
754              
755             }
756              
757             sub answer {
758              
759 0     0 1   my $me = shift();
760 0           my $answer = $me->_answer(@_);
761              
762             # Trim result of beginning and ending CR+LF (XXX)
763 0 0         if( defined $answer ) {
764 0           $answer =~ s/^[\r\n]+//;
765 0           $answer =~ s/[\r\n]+$//;
766             }
767              
768 0   0       $me->log->write('info', 'answer: `'.($answer||'').'\'' );
769              
770 0           return $answer;
771             }
772              
773             # parse_answer() cleans out answer() result as response code +
774             # useful information (useful in informative commands, for example
775             # Gsm command AT+CGMI)
776             sub parse_answer {
777 0     0 1   my $me = shift;
778              
779 0           my $buff = $me->answer( @_ );
780              
781             # Separate response code from information
782 0 0 0       if( defined $buff && $buff ne '' ) {
783              
784 0           my @buff = split /[\r\n]+/o, $buff;
785              
786             # Remove all empty lines before/after response
787 0           shift @buff while $buff[0] =~ /^[\r\n]+/o;
788 0           pop @buff while $buff[-1] =~ /^[\r\n]+/o;
789              
790             # Extract responde code
791 0           $buff = join( CR, @buff );
792 0           my $code = pop @buff;
793              
794             return
795             wantarray
796 0 0         ? ($code, @buff)
797             : $buff;
798              
799             } else {
800              
801 0           return '';
802              
803             }
804              
805             }
806              
807             1;
808              
809             =head1 NAME
810              
811             Device::Modem - Perl extension to talk to modem devices connected via serial port
812              
813             =head1 WARNING
814              
815             This is B software, so use it at your own risk,
816             and without B warranty! Have fun.
817              
818             =head1 SYNOPSIS
819              
820             use Device::Modem;
821              
822             my $modem = Device::Modem->new( port => '/dev/ttyS1' );
823              
824             if( $modem->connect( baudrate => 9600 ) ) {
825             print "connected!\n";
826             } else {
827             print "sorry, no connection with serial port!\n";
828             }
829              
830             $modem->attention(); # send `attention' sequence (+++)
831              
832             ($ok, $answer) = $modem->dial('02270469012'); # dial phone number
833             $ok = $modem->dial(3); # 1-digit parameter = dial number stored in memory 3
834              
835             $modem->echo(1); # enable local echo (0 to disable)
836              
837             $modem->offhook(); # Take off hook (ready to dial)
838             $modem->hangup(); # returns modem answer
839              
840             $modem->is_active(); # Tests whether modem device is active or not
841             # So far it works for modem OFF/ modem ON condition
842              
843             $modem->reset(); # hangup + attention + restore setting 0 (Z0)
844              
845             $modem->restore_factory_settings(); # Handle with care!
846             $modem->restore_factory_settings(1); # Same with preset profile 1 (can be 0 or 1)
847              
848             $modem->send_init_string(); # Send initialization string
849             # Now this is fixed to 'AT H0 Z S7=45 S0=0 Q0 V1 E0 &C0 X4'
850              
851             # Get/Set value of S1 register
852             my $S1 = $modem->S_register(1);
853             my $S1 = $modem->S_register(1, 55); # Don't do that if you definitely don't know!
854              
855             # Get status of managed signals (CTS, DSR, RLSD, RING)
856             my %signal = $modem->status();
857             if( $signal{DSR} ) { print "Data Set Ready signal active!\n"; }
858              
859             # Stores this number in modem memory number 3
860             $modem->store_number(3, '01005552817');
861              
862             $modem->repeat(); # Repeat last command
863              
864             $modem->verbose(1); # Normal text responses (0=numeric codes)
865              
866             # Some raw AT commands
867             $modem->atsend( 'ATH0' );
868             print $modem->answer();
869              
870             $modem->atsend( 'ATDT01234567' . Device::Modem::CR );
871             print $modem->answer();
872              
873              
874             =head1 DESCRIPTION
875              
876             C class implements basic B device abstraction.
877             It can be inherited by sub classes (as C), which are based on serial connections.
878              
879              
880             =head2 Things C can do
881              
882             =over 4
883              
884             =item *
885              
886             connect to a modem on your serial port
887              
888             =item *
889              
890             test if the modem is alive and working
891              
892             =item *
893              
894             dial a number and connect to a remote modem
895              
896             =item *
897              
898             work with registers and settings of the modem
899              
900             =item *
901              
902             issue standard or arbitrary C commands, getting results from modem
903              
904             =back
905              
906             =head2 Things C can't do yet
907              
908             =over 4
909              
910             =item *
911              
912             Transfer a file to a remote modem
913              
914             =item *
915              
916             Control a terminal-like (or a PPP) connection. This should really not
917             be very hard to do anyway.
918              
919             =item *
920              
921             Many others...
922              
923             =back
924              
925             =head2 Things it will never be able to do
926              
927             =over 4
928              
929             =item *
930              
931             Coffee :-)
932              
933             =back
934              
935              
936             =head2 Examples
937              
938             In the `examples' directory, there are some scripts that should work without big problems,
939             that you can take as (yea) examples:
940              
941             =over 4
942              
943             =item `examples/active.pl'
944              
945             Tests if modem is alive
946              
947             =item `examples/caller-id.pl'
948              
949             Waits for an incoming call and displays date, time and phone number of the caller.
950             Normally this is available everywhere, but you should check your local phone line
951             and settings.
952              
953             =item `examples/dial.pl'
954              
955             Dials a phone number and display result of call
956              
957             =item `examples/shell.pl'
958              
959             (Very) poor man's minicom/hyperterminal utility
960              
961             =item `examples/xmodem.pl'
962              
963             First attempt at a test script to receive a file via xmodem protocol.
964             Please be warned that this thing does not have a chance to work. It's
965             only a (very low priority) work in progress...
966              
967             If you want to help out, be welcome!
968              
969              
970             =back
971              
972             =head1 METHODS
973              
974             =head2 answer()
975              
976             One of the most used methods, waits for an answer from the device. It waits until
977             $timeout (seconds) is reached (but don't rely on this time to be very correct) or until an
978             expected string is encountered. Example:
979              
980             $answer = $modem->answer( [$expect [, $timeout]] )
981              
982             Returns C<$answer> that is the string received from modem stripped of all
983             B and B chars B at the beginning and at the end of the
984             string. No in-between B are stripped.
985              
986             Note that if you need the raw answer from the modem, you can use the _answer() (note
987             that underscore char before answer) method, which does not strip anything from the response,
988             so you get the real modem answer string.
989              
990             Parameters:
991              
992             =over 4
993              
994             =item *
995              
996             C<$expect> - Can be a regexp compiled with C or a simple substring. Input coming from the
997             modem is matched against this parameter. If input matches, result is returned.
998              
999             =item *
1000              
1001             C<$timeout> - Expressed in milliseconds. After that time, answer returns result also if nothing
1002             has been received. Example: C<10000>. Default: C<$Device::Modem::TIMEOUT>, currently 500 ms.
1003              
1004             =back
1005              
1006              
1007              
1008             =head2 atsend()
1009              
1010             Sends a raw C command to the device connected. Note that this method is most used
1011             internally, but can be also used to send your own custom commands. Example:
1012              
1013             $ok = $modem->atsend( $msg )
1014              
1015             The only parameter is C<$msg>, that is the raw AT command to be sent to
1016             modem expressed as string. You must include the C prefix and final
1017             B and/or B manually. There is the special constant
1018             C that can be used to include such a char sequence into the at command.
1019              
1020             Returns C<$ok> flag that is true if all characters are sent successfully, false
1021             otherwise.
1022              
1023             Example:
1024              
1025             # Enable verbose messages
1026             $modem->atsend( 'AT V1' . Device::Modem::CR );
1027              
1028             # The same as:
1029             $modem->verbose(1);
1030              
1031              
1032             =head2 attention()
1033              
1034             This command sends an B sequence to modem. This allows modem
1035             to pass in B and accept B commands. Example:
1036              
1037             $ok = $modem->attention()
1038              
1039             =head2 connect()
1040              
1041             Connects C object to the specified serial port.
1042             There are options (the same options that C has) to control
1043             the parameters associated to serial link. Example:
1044              
1045             $ok = $modem->connect( [%options] )
1046              
1047             List of allowed options follows:
1048              
1049             =over 4
1050              
1051             =item C
1052              
1053             Controls the speed of serial communications. The default is B<19200> baud, that should
1054             be supported by all modern modems. However, here you can supply a custom value.
1055             Common speed values: 300, 1200, 2400, 4800, 9600, 19200, 38400, 57600,
1056             115200.
1057             This parameter is handled directly by C object.
1058              
1059             =item C
1060              
1061             This tells how many bits your data word is composed of.
1062             Default (and most common setting) is C<8>.
1063             This parameter is handled directly by C object.
1064              
1065             =item C
1066              
1067             Sets the handshake (or flow control) method for the serial port.
1068             By default it is C, but can be either C (hardware flow control)
1069             or C (software flow control). These flow control modes may or may not
1070             work depending on your modem device or software.
1071              
1072             =item C
1073              
1074             Custom initialization string can be supplied instead of the built-in one, that is the
1075             following: C, that is taken shamelessly from
1076             C utility, I think.
1077              
1078             =item C
1079              
1080             Controls how parity bit is generated and checked.
1081             Can be B, B or B. Default is B.
1082             This parameter is handled directly by C object.
1083              
1084             =item C
1085              
1086             Tells how many bits are used to identify the end of a data word.
1087             Default (and most common usage) is C<1>.
1088             This parameter is handled directly by C object.
1089              
1090             =back
1091              
1092              
1093              
1094             =head2 dial()
1095              
1096             Dials a telephone number. Can perform both voice and data calls.
1097              
1098             Usage:
1099              
1100             $ok = $modem->dial($number);
1101             $ok = $modem->dial($number, $timeout);
1102             $ok = $modem->dial($number, $timeout, $mode);
1103              
1104             Takes the modem off hook, dials the specified number and returns
1105             modem answer.
1106              
1107             Regarding voice calls, you B be able to send your voice through.
1108             You probably have to connect an analog microphone, and just speak.
1109             Or use a GSM phone. For voice calls, a simple C<;> is appended to the
1110             number to be dialed.
1111              
1112             If the number to dial is 1 digit only, extracts the number from the address book, provided your device has one. See C.
1113              
1114             Examples:
1115              
1116             # Simple usage. Timeout and mode are optional.
1117             $ok = $mode->dial('123456789');
1118              
1119             # List context: allows to get at exact modem answer
1120             # like `CONNECT 19200/...', `BUSY', `NO CARRIER', ...
1121             # Also, 30 seconds timeout
1122             ($ok, $answer) = $modem->dial('123456789', 30);
1123              
1124             If called in B, returns only success of connection.
1125             If modem answer contains the C string, C returns
1126             successful state, otherwise a false value is returned.
1127              
1128             If called in B, returns the same C<$ok> flag, but also the
1129             exact modem answer to the dial operation in the C<$answer> scalar.
1130             C<$answer> typically can contain strings like:
1131              
1132             =over 4
1133              
1134             =item C
1135              
1136             =item C
1137              
1138             =item C
1139              
1140             =back
1141              
1142             and so on ... all standard modem answers to a dial command.
1143              
1144             Parameters are:
1145              
1146             =over 4
1147              
1148             =item C<$number>
1149              
1150             B, this is the phone number to dial.
1151             If C<$number> is only 1 digit, it is interpreted as:
1152             B>.
1153              
1154             So if your code is:
1155              
1156             $modem->dial( 2, 10 );
1157              
1158             This means: dial number in the modem internal address book
1159             (see C for a way to read/write address book)
1160             in position number B<2> and wait for a timeout of B<10> seconds.
1161              
1162             =item C<$timeout>
1163              
1164             B, default is B<30 seconds>.
1165              
1166             Timeout expressed in seconds to wait for the remote device
1167             to answer. Please do not expect an B wait for the number of
1168             seconds you specified.
1169              
1170             =item C<$mode>
1171              
1172             B, default is C, as string.
1173             Allows to specify the type of call. Can be either:
1174              
1175             =over 4
1176              
1177             =item C (default)
1178              
1179             To perform a B.
1180              
1181             =item C
1182              
1183             To perform a B, if your device supports it.
1184             No attempt to verify whether your device can do that will be made.
1185              
1186             =back
1187              
1188             =back
1189              
1190             =head2 disconnect()
1191              
1192             Disconnects C object from serial port. This method calls underlying
1193             C of C object.
1194             Example:
1195              
1196             $modem->disconnect();
1197              
1198             =head2 echo()
1199              
1200             Enables or disables local echo of commands. This is managed automatically by C
1201             object. Normally you should not need to worry about this. Usage:
1202              
1203             $ok = $modem->echo( $enable )
1204              
1205             =head2 hangup()
1206              
1207             Does what it is supposed to do. Hang up the phone thus terminating any active call.
1208             Usage:
1209              
1210             $ok = $modem->hangup();
1211              
1212             =head2 is_active()
1213              
1214             Can be used to check if there is a modem attached to your computer.
1215             If modem is alive and responding (on serial link, not to a remote call),
1216             C returns true (1), otherwise returns false (0).
1217              
1218             Test of modem activity is done through DSR (Data Set Ready) signal. If
1219             this signal is in off state, modem is probably turned off, or not working.
1220             From my tests I've found that DSR stays in "on" state after more or less
1221             one second I turn off my modem, so know you know that.
1222              
1223             Example:
1224              
1225             if( $modem->is_active() ) {
1226             # Ok!
1227             } else {
1228             # Modem turned off?
1229             }
1230              
1231             =head2 log()
1232              
1233             Simple accessor to log object instanced at object creation time.
1234             Used internally. If you want to know the gory details, see C objects.
1235             You can also see the B for how to log something without knowing
1236             all the gory details.
1237              
1238             Hint:
1239             $modem->log->write('warning', 'ok, my log message here');
1240              
1241             =head2 new()
1242              
1243             C constructor. This takes several options. A basic example:
1244              
1245             my $modem = Device::Modem->new( port => '/dev/ttyS0' );
1246              
1247             if under Linux or some kind of unix machine, or
1248              
1249             my $modem = Device::Modem->new( port => 'COM1' );
1250              
1251             if you are using a Win32 machine.
1252              
1253             This builds the C object with all the default parameters.
1254             This should be fairly usable if you want to connect to a real modem.
1255             Note that I'm testing it with a B<3Com US Robotics 56K Message> modem
1256             at B<19200> baud and works ok.
1257              
1258             List of allowed options:
1259              
1260             =over 4
1261              
1262             =item *
1263              
1264             C - serial port to connect to. On Unix, can be also a convenient link as
1265             F (the default value). For Win32, C can be used.
1266              
1267             =item *
1268              
1269             C - this specifies the method and eventually the filename for logging.
1270             Logging process with C is controlled by B, stored under
1271             F folder. At present, there are two main plugins: C and C.
1272             C does not work with Win32 machines.
1273             When using C plug-in, all log information will be written to a default filename
1274             if you don't specify one yourself. The default is F<%WINBOOTDIR%\temp\modem.log> on
1275             Win32 and F on Unix.
1276              
1277             Also there is the possibility to pass a B, if this object
1278             provides the following C call:
1279              
1280             $log_object->write( $loglevel, $logmessage )
1281              
1282             You can simply pass this object (already instanced) as the C property.
1283              
1284             Examples:
1285              
1286             # For Win32, default is to log in "%WINBOOTDIR%/temp/modem.log" file
1287             my $modem = Device::Modem->new( port => 'COM1' );
1288              
1289             # Unix, custom logfile
1290             my $modem = Device::Modem->new( port => '/dev/ttyS0', log => 'file,/home/neo/matrix.log' )
1291              
1292             # With custom log object
1293             my $modem = Device::modem->new( port => '/dev/ttyS0', log => My::LogObj->new() );
1294              
1295             =item *
1296              
1297             C - default logging level. One of (order of decrescent verbosity): C,
1298             C, C, C, C, C, C, C, C.
1299              
1300             =back
1301              
1302              
1303             =head2 offhook()
1304              
1305             Takes the modem "off hook", ready to dial. Normally you don't need to use this.
1306             Also C goes automatically off hook before dialing.
1307              
1308              
1309              
1310             =head2 parse_answer()
1311              
1312             This method works like C, it accepts the same parameters, but it
1313             does not return the raw modem answer. Instead, it returns the answer string
1314             stripped of all B/B characters at the beginning B at the end.
1315              
1316             C is meant as an easy way of extracting result code
1317             (C, C, ...) and information strings that can be sent by modem
1318             in response to specific commands. Example:
1319              
1320             > AT xSHOW_MODELx
1321             US Robotics 56K Message
1322             OK
1323             >
1324              
1325             In this example, C is the result and C is the
1326             informational message.
1327              
1328             In fact, another difference with C is in the return value(s).
1329             Here are some examples:
1330              
1331             $modem->atsend( '?my_at_command?' );
1332             $answer = $modem->parse_answer();
1333              
1334             where C<$answer> is the complete response string, or:
1335              
1336             ($result, @lines) = $modem->parse_answer();
1337              
1338             where C<$result> is the C or C final message and C<@lines> is
1339             the array of information messages (one or more lines). For the I example,
1340             C<$result> would hold "C" and C<@lines> would consist of only 1 line with
1341             the string "C".
1342              
1343              
1344             =head2 port()
1345              
1346             Used internally. Accesses the C underlying object. If you need to
1347             experiment or do low-level serial calls, you may want to access this. Please report
1348             any usage of this kind, because probably (?) it is possible to include it in a higher
1349             level method.
1350              
1351             As of 1.52, C will automatically try to reconnect if it detects
1352             a bogus underlying port object. It will reconnect with the same options used
1353             when Cing the first time.
1354              
1355             If no connection has taken place yet, then B
1356             will be attempted.
1357              
1358             =head2 repeat()
1359              
1360             Repeats the last C command issued.
1361             Usage:
1362              
1363             $ok = $modem->repeat()
1364              
1365              
1366             =head2 reset()
1367              
1368             Tries in any possible way to reset the modem to the starting state, hanging up all
1369             active calls, resending the initialization string and preparing to receive C
1370             commands.
1371              
1372              
1373              
1374             =head2 restore_factory_settings()
1375              
1376             Restores the modem default factory settings. There are normally two main "profiles",
1377             two different memories for all modem settings, so you can load profile 0 and profile 1,
1378             that can be different depending on your modem manufacturer.
1379              
1380             Usage:
1381              
1382             $ok = $modem->restore_factory_settings( [$profile] )
1383              
1384             If no C<$profile> is supplied, C<0> is assumed as default value.
1385              
1386             Check on your modem hardware manual for the meaning of these B.
1387              
1388              
1389              
1390             =head2 S_register()
1391              
1392             Gets or sets an B value. These are some internal modem registers that
1393             hold important information that controls all modem behaviour. If you don't know
1394             what you are doing, don't use this method. Usage:
1395              
1396             $value = $modem->S_register( $reg_number [, $new_value] );
1397              
1398             C<$reg_number> ranges from 0 to 99 (sure?).
1399             If no C<$new_value> is supplied, return value is the current register value.
1400             If a C<$new_value> is supplied (you want to set the register value), return value
1401             is the new value or C if there was an error setting the new value.
1402              
1403            
1404              
1405             Examples:
1406              
1407             # Get value of S7 register
1408             $modem->S_register(7);
1409              
1410             # Set value of S0 register to 0
1411             $modem->S_register(0, 0);
1412              
1413              
1414             =head2 send_init_string()
1415              
1416             Sends the initialization string to the connected modem. Usage:
1417              
1418             $ok = $modem->send_init_string( [$init_string] );
1419              
1420             If you specified an C as an option to C object constructor,
1421             that is taken by default to initialize the modem.
1422             Else you can specify C<$init_string> parameter to use your own custom initialization
1423             string. Be careful!
1424              
1425             =head2 status()
1426              
1427             Returns status of main modem signals as managed by C (or C) objects.
1428             The signals reported are:
1429              
1430             =over 4
1431              
1432             =item CTS
1433              
1434             Clear to send
1435              
1436             =item DSR
1437              
1438             Data set ready
1439              
1440             =item RING
1441              
1442             Active if modem is ringing
1443              
1444             =item RLSD
1445              
1446             ??? Released line ???
1447              
1448             =back
1449              
1450             Return value of C call is a hash, where each key is a signal name and
1451             each value is > 0 if signal is active, 0 otherwise.
1452             Usage:
1453              
1454             ...
1455             my %sig = $modem->status();
1456             for ('CTS','DSR','RING','RLSD') {
1457             print "Signal $_ is ", ($sig{$_} > 0 ? 'on' : 'off'), "\n";
1458             }
1459              
1460             =head2 store_number()
1461              
1462             Store telephone number in modem internal address book, to be dialed later (see C method).
1463             Usage:
1464              
1465             $ok = $modem->store_number( $position, $number )
1466              
1467             where C<$position> is the address book memory slot to store phone number (usually from 0 to 9),
1468             and C<$number> is the number to be stored in the slot.
1469             Return value is true if operation was successful, false otherwise.
1470              
1471             =head2 verbose()
1472              
1473             Enables or disables verbose messages. This is managed automatically by C
1474             object. Normally you should not need to worry about this. Usage:
1475              
1476             $ok = $modem->verbose( $enable )
1477              
1478             =head2 wait()
1479              
1480             Waits (yea) for a given amount of time (in milliseconds). Usage:
1481              
1482             $modem->wait( [$msecs] )
1483              
1484             Wait is implemented via C
1485             Don't know if this is really a problem on some platforms.
1486              
1487             =head2 write_drain()
1488              
1489             Only a simple wrapper around C method.
1490             Disabled for Win32 platform, that doesn't have that.
1491              
1492              
1493             =head1 REQUIRES
1494              
1495             =over 4
1496              
1497             =item Device::SerialPort (Win32::SerialPort for Win32 machines)
1498              
1499             =back
1500              
1501             =head1 EXPORT
1502              
1503             None
1504              
1505              
1506              
1507             =head1 TO-DO
1508              
1509             =over 4
1510              
1511             =item AutoScan
1512              
1513             An AT command script with all interesting commands is run
1514             when `autoscan' is invoked, creating a `profile' of the
1515             current device, with list of supported commands, and database
1516             of brand/model-specific commands
1517              
1518             =item Serial speed auto-detect
1519              
1520             Now if you connect to a different baud rate than that of your modem,
1521             probably you will get no response at all. It would be nice if C
1522             could auto-detect the speed to correctly connect at your modem.
1523              
1524             =item File transfers
1525              
1526             It would be nice to implement C<[xyz]modem> like transfers between
1527             two C objects connected with two modems.
1528              
1529             =back
1530              
1531              
1532             =head1 FAQ
1533              
1534             There is a minimal FAQ document for this module online at
1535             L
1536              
1537             =head1 SUPPORT
1538              
1539             Please feel free to contact me at my e-mail address L
1540             for any information, to resolve problems you can encounter with this module
1541             or for any kind of commercial support you may need.
1542              
1543             =head1 AUTHOR
1544              
1545             Cosimo Streppone, L
1546              
1547             =head1 COPYRIGHT
1548              
1549             (C) 2002-2014 Cosimo Streppone, L
1550              
1551             This library is free software; you can only redistribute it and/or
1552             modify it under the same terms as Perl itself.
1553              
1554             =head1 SEE ALSO
1555              
1556             Device::SerialPort,
1557             Win32::SerialPort,
1558             Device::Gsm,
1559             perl
1560              
1561             =cut
1562              
1563             # vim: set ts=4 sw=4 tw=120 nowrap nu