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