Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Wanet Telecoms Ltd on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Device::SerialPort handshake detection 1

Status
Not open for further replies.

svar

Programmer
Aug 12, 2001
349
GR
I need to use the modem to connect to another one
and particularly pay attention to errors. Many errors are possible, but here I want to focus on the case where the other side is not a modem(i.e. has unplugged the PC and plugged in the normal phone)
Here is an

use Device::SerialPort;
#

my $dialled_no='......';


&start_dialing($dialled_no);


sub start_dialing
{my $number=shift;
my $modem=new Device::SerialPort('/dev/cuad0') or die
"Unable to pen /dev/cuad0\n";

### Question no 1: What do I use instead of /dev/cuad0 if
### this will be used from a Windows machine?

# $modem->baudrate(115200);
$modem->baudrate(9600);
$modem->parity("none");
$modem->databits(8);
$modem->stopbits(1);
$modem->write("ATH;\n");

$modem->write("ATDT $number;\n");

### here I am unsure as to how you actually make the call and grab the other modem responses.

}
 
For windows you should be using Win32::SerialPort, rather than Device::SerialPort

Paul
------------------------------------
Spend an hour a week on CPAN, helps cure all known programming ailments ;-)
 
Ok,
so
$PortObj = new Win32::SerialPort ($PortName, $quiet)
|| die "Can't open $PortName: $^E\n"; # $quiet is option

what would be an example of $portName? 'COM1' ?

It is also unclear to me how I could check the answer from the modem, at the other end, or its absence

With Unix, I guess the simplest way to do this would be
"system wvdial $dialled_number | grep ...." or something similar, i.e. I don't really need that fine control of
the connection, all I need is to be able to specify a number to call and check the response from the other side.
But I need to do this in Windows and I cannot find how to call dialer.exe from the command line with the dialled number(and possibly other parameters) as an argument.
 
COM1 or whatever port the modem is connected to in the control panel

The docs for Win32::SerialPort should have a simple example of communication between two modems

What are you using this for, if you don't mind me asking, there may be other ways?

Paul
------------------------------------
Spend an hour a week on CPAN, helps cure all known programming ailments ;-)
 
The idea is a security scan for nonauthorized modems on a network(policy is that users should not have modems, so
scanning all numbers in the corporate network should trigger an alert if a modem answers on the other end).
So basically
-call all numbers sequentially
-raise an alert if a modem answers.

That's basically all there is to it
 
You can determine if there's modems just by scanning the registry of pcs on the network, which would be quieter, no? If it's a security thing, and there's modems, and all of a sudden they start dialling, if there's a perp in the vicinity, they's well tipped off now, no?

Anyhoo, how's it going?

Paul
------------------------------------
Spend an hour a week on CPAN, helps cure all known programming ailments ;-)
 
True, assuming one has access to the other PC's registry. As you can see from the other thread
I am trying both approaches.

Back to the question in hand, the idea is to call
using the modem and see if a modem answers(meaning getting a 'CONNECT'). I tested what would happen if I dial a non-modem and I usually get 'NO CARRIER', which I think is correct, but I also got sometimes 'NO ANSWER', which looks strange(note in all test, the same number was dialled -which is behind a PBX though).
I have not tested the code yet(I do not have a windows machine with a modem-it's only now that I am forced to use Windows and check windows), but if I understand it correctly, it should run something like this:

# First, define the Portname Object
use Win32::SerialPort ;
my $PortObj= new Win32::SerialPort('COM1') or die "cannot open COM1: $^E\n";
# Next, configure( as I understand this is compulsory)
$PortObj->baudrate(9600);
$PortObj->parity("odd");
$PortObj->databits(8);
$PortObj->stopbits(1);
#Next, do the call
my $phone=1234567;

## This I have not found the command for!!!!
#Next, capture response and look for connect
my ($match,$after,'CONNECT',$instead)=$PortObj->lastlook;

if($match){#found a CONNECT
print "found a modem for phone $phone\n";
}


Any ideas?
 
Thanks, glad to see it's the same as the call in the corresponding Unix module(Device::SerialPort). Shouldn't there be a space between ATDT and $phone?
 
it's been a while since I wrote directly to modems, but I seem to remember a space, try it and see

Paul
------------------------------------
Spend an hour a week on CPAN, helps cure all known programming ailments ;-)
 
Ok, the question now is how does one grab the input?

my ($match,$after,'CONNECT',$instead)=$ob->lastlook;

? because this does not seem to work
 
show us what you got to date, there's some good examples on the link above ...

Paul
------------------------------------
Spend an hour a week on CPAN, helps cure all known programming ailments ;-)
 
Here is the script with a Tk-interface, the main routine lifted from the examples, but... it does not work(it does dial, but does not capture what comes back)

#!/usr/bin/perl -w
# cross-platform example7, use LF-only on Un*x
###TODO: Can we autodetect port?
use strict;
use Tk;
require('dumpvar.pl');
use vars qw( $OS_win $ob $file $port);
my $min; my $max;
$file = 'MODEM_CONFIG_PARAMS';

BEGIN {
$OS_win = ($^O eq "MSWin32") ? 1 : 0;
if ($OS_win) {
eval "use Win32::SerialPort 0.13";
die "$@\n" if ($@);
$port = 'COM2';
$ob = Win32::SerialPort->new ($port);
}
else {
eval "use Device::SerialPort";
die "$@\n" if ($@);
$port = '/dev/modem';
$ob = Device::SerialPort->new ($port);
}
} # End BEGIN
my $top= MainWindow->new();
$top->title("Modem checker Configuration Menu");
my $menubar = $top->Frame;
$menubar ->pack(-side =>'top', -fill =>'x');
$menubar ->configure (-fg =>'red', -bg =>'blue', -relief =>'raised');
my $filemenu =$menubar->Menubutton(-text =>'File', -underline =>0);
$filemenu ->command(-label => 'Quit', -underline =>0, -command =>sub{$top->destroy()});
$filemenu->pack(-side =>'left');
$filemenu->configure(-fg =>'red', -bg =>'blue', -relief =>'raised');
my $frame=$top->Frame(-bg=>'aquamarine',-relief=>'sunken')->pack();
my $label0=$frame->Label(-text=>'Enter Phone Number Ranges to scan')->grid(-row=>0, -column=>0); ;
my $label=$frame->Label(-text=>'Starting number:')->grid(-row=>1,-column=>0);
my $entry=$frame->Entry(-textvariable=>\$min)->grid(-row=>1,-column=>1);
my $label2=$frame->Label(-text=>'Ending number:')->grid(-row=>2,-column=>0);
my $entry2=$frame->Entry(-textvariable=>\$max)->grid(-row=>2,-column=>1);

my $label3=$frame->Label(-text=>'Port for modem of the computer used to perform the scan(present computer)')->grid(-row=>3,-column=>0);
my $entry3=$frame->Entry(-textvariable=>\$port)->grid(-row=>3,-column=>1);

my $button=$frame->Button(-bg=>'firebrick1',-text=>'Start the scan',
-command=>sub{
#first, error handler
if ($min=~/\D/ or $max=~/\D/){
my $TOP=MainWindow->new();
$TOP->title('Error Message in range specification');
$TOP->Label(-text=>"Invalid(nondigit) input $min and $max",-bg=>'firebrick1')->pack();
my $buttoner=$TOP->Button(-bg=>'salmon1',-text=>'Ok',
-command=>sub{$TOP->destroy();});
&MainLoop();
}#if min or max=~/D

if (-e $file){

if ($OS_win){$ob = Win32::SerialPort->start ($file);}
else {$ob = Device::SerialPort->start ($file);}
die "Can't open serial port from $file: $^E\n" unless ($ob);
}#file exists
else {# file does not exist, create it!

if ($OS_win) {
$port = 'COM2';
$ob = Win32::SerialPort->new ($port);
}
else {
$port = '/dev/modem';
$ob = Device::SerialPort->new ($port);
}
unless($ob){
my $TOPob=MainWindow->new();
$TOPob->title("cannot open Serial Port $port");
$TOPob->Label(-text=>"cannot open Serial Port $port",-bg=>'firebrick1')->pack();
my $buttonob=$TOPob->Button(-bg=>'salmon1',-text=>'Ok',
-command=>sub{$TOPob->destroy();});
&MainLoop();
}#unless $ob

$ob->user_msg(1); # misc. warnings
$ob->error_msg(1); # hardware and data errors

$ob->baudrate(38400);
$ob->parity("none");
## $ob->parity_enable(1); # for any parity except "none"
$ob->databits(8);
$ob->stopbits(1);
$ob->handshake('rts');

$ob->write_settings;
$ob->save("$file");

print "wrote configuration file $file\n";

}#create it!
$ob->are_match("BUSY","CONNECT","OK","NO DIALTONE","ERROR","RING",
"NO CARRIER","NO ANSWER");
open(OUT,">DETECTED_MODEMS") or die "cannot open file DETECTED_MODEMS for writing\n";
if($min>$max){my $tmp=$min; $min=$max; $max=$tmp;
print "min and max entered in wrong order, revered them...\n";}
my $dialled_no;
for ($dialled_no=$min; $dialled_no<=$max; $dialled_no++ ){
&dial($dialled_no,$ob); }
close(OUT);
})->grid(-row=>4,-column=>1);

my $quitbut= $frame->Button(-bg=>'blue',-text=>'Stop the scan', -command=>sub{
$top->destroy();
})->grid(-row=>5,-column=>1);

&MainLoop();


sub waitfor {
my $ob=shift; my $timeout=$ob->get_tick_count + (1000 * shift);
$ob->lookclear; # clear buffers
my $gotit = "";

for (;;) {
return unless (defined ($gotit = $ob->lookfor));
if ($gotit ne "") {
my ($found, $end) = $ob->lastlook;
return $gotit.$found;
}
return if ($ob->reset_error);
return if ($ob->get_tick_count > $timeout);
}
}

# =============== execution begins here =======================



#print "\n5 seconds to failure..\n";
#waitfor(5) || print "Timed Out\n";

#undef $ob;
#------ get parameters


sub dial{my $phone=shift; my $ob=shift;
$ob->write("ATE0X4\r");
printf "%s\n", waitfor($ob,1); # 1 second
print "\nStarting Dial\n";
$ob->write("ATDT$phone\r") || die "Could Not Dial\n";
print "%s\n", waitfor($ob,20);
&main::dumpValue($ob);
printf "%s\n", waitfor($ob,20);
print "\n5 seconds to failure..\n";
waitfor($ob,5) || print "Timed Out\n";
my $match; my $after; my $instead;
my $result = $ob->input;
print "result = $result\n";
print "Starting 500 character background read\n";
my $in; print "oswin=$OS_win\n";
$in = $ob->read_bg(500) if ($OS_win);
print "in=$in\n" if ($OS_win);
#Next, capture response and look for connect
my $waiter=0;
while($waiter<20){
my $con1='CONNECT';
($match,$after,$con1,$instead)=$ob->lastlook;

if($match){#found a CONNECT
print OUT "found a modem for phone $phone match=$match\n";
}
sleep(2); $waiter++;}

$ob->write("ATZ\r") || die "Could Not reset \n";

}

 
isolate what doesn't work into a smaller script without the interface and then work on that

Paul
------------------------------------
Spend an hour a week on CPAN, helps cure all known programming ailments ;-)
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top