Testing the Modem class: The ModemATTest

11 May

Testing the Modem class: The ModemATTest

The ModemATTest class uses the Modem class to send AT commands to a modem. It takes the serial port to open as the first command line argument, then AT commands after that.

Listing 13-2: ModemATTest.java

import java.io.*;

import javax.comm.*;

public class ModemATTest   {

public static void main(String[] args) { Modem external = new Modem(); external.openSerialPort(args[0]);

for (int i=1; i<args.length; i++) {

external.sendCommand(args[i]);

}

}

}

For this example, we’re using a TINI connected to a PC via Ethernet, and we’ve connected the TINI to an external modem via the specially made cross-over cable. To compile the program, create a separate src folder and place the ModemATTest.java

in it, as well as Modem.java. Make a bin folder in the same directory. Then type the

following:

C:\> cd src

C:\> javac -bootclasspath %TINI_HOME%\bin\tiniclasses.jar

-d ..\bin ModemATTest.java

C:\> cd ..

C:\> java -classpath %TINI_HOME%\bin\tini.jar;. BuildDependency

-p %TINI_HOME%\bin\owapi_dependencies_TINI.jar

-f bin

-x %TINI_HOME%\bin\owapi_dep.txt

-o bin\ModemATTest.tini

-d %TINI_HOME%\bin\tini.db

As we’ve done in previous examples, some of the command line arguments for the java command have been shown on a separate line. Everything after java should be entered on the same line. Transfer the .tini file to your TINI stick via FTP, and via Telnet attempt the following:

TINI /> java ModemATTest.tini serial0 AT ATM1L0 ATE0 AT ATE1 AT

Sending: AT Receiving: AT

OK

Sending: ATM1L0

Receiving: ATM1L0

OK

Sending: ATE0

Receiving: ATE0

OK

Sending: AT Receiving:

OK

Sending: ATE1

Receiving: OK

Sending: AT Receiving: AT

OK

What did we just do?  Entering AT by itself does nothing, but will inspire the modem to respond with an OK. Entering M1L0 tells the speaker to stay on until the carrier is detected and makes the volume low. The commands E0 and E1 allow you to turn off or turn on the echoing of commands in the response. If this didn’t work, you may want to double check the cable or connect the modem to the PC with a straight-

through cable and try the same command sequences in a terminal emulator (since this program is not TINI specific and does not use any TINI classes it will run fine on

your PC from either Windows or Linux—just remember to specify the proper serial port for your operating system). If it did work, then we’re ready to move on to the next step.

A Modem Dialing Test: The ModemDialTest  class

The ModemDialTest class uses the dial() method of the Modem class to dial out to an ISP. It exits after receiving the CONNECT message from the modem. You need to put the phone number of your own ISP where you see 5555555555. The program takes as arguments the serial port you plan on using for the connection, and a series of strings representing the AT commands in your dialing string. The program is very similar to our previous example, ModemATTest, with the addition of code that waits for the CONNECT.

Listing 13-3: ModemDialTest.java

import java.io.*;

import javax.comm.*;

public class ModemDialTest   {

public static void main(String[] args) { Modem external = new Modem();

String[] dialString=new String[(args.length)-1];

external.openSerialPort(args[0]);

for (int i=0;i<(args.length)-1; i++) {

dialString[i]=args[i+1];

}

external.dial(dialString);

}

}

We’re still using a TINI connected to a PC via Ethernet, and we’ve connected the TINI to an external modem via the specially made crossover cable. To compile the program, create a separate folder and place the ModemDialTest.java in it, as well as Modem.java. Make a bin folder in the same directory. Then type the following:

C:\> cd src

C:\> javac -bootclasspath %TINI_HOME%\bin\tiniclasses.jar

-d ..\bin ModemDialTest.java

C:\> cd ..

C:\> java -classpath %TINI_HOME%\bin\tini.jar;. BuildDependency

-p %TINI_HOME%\bin\owapi_dependencies_TINI.jar

-f bin

-x %TINI_HOME%\bin\owapi_dep.txt

-o bin\ModemDialTest.tini

-d %TINI_HOME%\bin\tini.db

As we’ve done in previous examples, some of the command line arguments for the java command have been shown on a separate line. Everything after java should be entered on the same line. Transfer the .tini file to your TINI stick via FTP, and via Telnet attempt the following:

TINI /> java ModemDialTest.tini serial0 AT ATM1L0 ATDT5555555555

Sending: AT Receiving:

Sending: ATM1L0

Receiving: AT

OK ATM1L0

OK

Sending: ATDT5555555555

Receiving: ATDT5555555555

CONNECT 48000

PROTOCOL:LAPM

Once again, for the example, we’ve pasted over the actual phone number we used with the 5555555555. You need to put the phone number of your ISP in your dialing string on the command line. If this worked, and you get results similar to the above in that the CONNECT was received, then we’re ready to move on to considering the PPP client connection. If this didn’t work, you need to determine whether it’s a problem with the

AT commands you’re sending to the modem, or something related to the cable, etc. The AT command string can be debugged by putting the modem back on the PC and trying the same commands in a terminal emulator. If they don’t work, consider commands such as &F (restore factory defaults), &K0 (disable flow control), X4(provide all responses), and E0 (turn off command echoing). If the command string works on PC

but not on the TINI, then you need to double check the cable.

Example: Dialing out to an ISP (TINI as a PPP Client)

In the previous sections, we looked at ways of getting the TINI stick talking with a modem. Now it’s time to focus our attention on actually implementing a PPP connection on a TINI. We’ll start this by making a PPP client program. In this context, a client means that we’ll be dialing out to an ISP and receiving a server assigned IP address from them. It is important to note that the ISP is going to want us to supply a username and password, and that the TINI PPP API supports only Password Authentication Protocol (PAP) for

this. Your ISP will have to support PAP, or this won’t work. In our earlier discussion of the

PPP API, we noted that to handle PPP connections, we have to provide an implementation of the PPPEventListener. This will be the bulk of our PPP client program.

The  PPPClient class

To make the TINI stick act as a PPP client, dialing out to an ISP to establish a PPP connection, we will make a program that dials out to the ISP, creates a PPP object, and implements the PPPEventListener. This class is called PPPClient. We’ll show it in its entirety below, and then work our way through it.

Listing 13-4: PPPClient.java

import java.io.*;

import javax.comm.*;

import com.dalsemi.tininet.ppp.*;

public class PPPClient implements PPPEventListener {

static SerialPort serialPort = null;

static PPP ppp;

public void pppEvent (PPPEvent e) {

switch(e.getEventType()) {

case PPPEvent.STARTING:

System.out.println(“PPP sent the STARTING event!”);

ppp.up(serialPort);

break;

case PPPEvent.UP:

System.out.println(“PPP sent the UP event!”);

ppp.addInterface(“ppp0”);

break;

case PPPEvent.AUTHENTICATION_REQUEST:

//We don’t have to do anything here, because

//We’re dialing out TO a server. break;

case PPPEvent.STOPPED: System.out.println(“Calling ppp.close()” ); ppp.close();

break;

case PPPEvent.CLOSED:

System.out.println(“PPP sent the CLOSED event!”);

ppp.down(); ppp.removeEventListener(this); serialPort.close(); System.exit(0);

break;

default:

System.out.println( “Some other ppp event happened” );

break;

}

}

public static void main(String[] args) {

String[] dialString=new String[(args.length)-2];

for (int i=0;i<(args.length)-2; i++) {

dialString[i]=args[i+2];

}

Modem external = new Modem(); external.openSerialPort(“serial0”); serialPort = external.serialPort; PPPClient ourListener = new PPPClient(); ppp = new PPP();

byte[] localAddress = new byte[] {0, 0, 0, 0}; byte[] remoteAddress = new byte[] {0, 0, 0, 0}; try {

ppp.addEventListener(ourListener); ppp.setLocalAddress(localAddress); ppp.setRemoteAddress(remoteAddress); ppp.setACCM(0×00000000); ppp.setAuthenticate(false); ppp.setUsername(args[0]); ppp.setPassword(args[1]); ppp.setDefaultInterface(true);

} catch(Exception e) { System.out.println(e);

System.out.println(“The ppp methods failed”);

serialPort.close(); System.exit(0);

}

if (external.dial(dialString)) {

ppp.open();

} else {

System.out.println(“The dialer failed!”);

serialPort.close(); System.exit(0);

}

while(true) {

//run forever…

}

}

}

We start by importing the necessary java classes. We now are using classes specific to TINI: com.dalsemi.tininet.ppp.* We declare our class, and our member variables. We only have two variables, a SerialPort object and a PPP object.

import java.io.*;

import javax.comm.*;

import com.dalsemi.tininet.ppp.*;

public class PPPClient implements PPPEventListener {

static SerialPort serialPort = null;

static PPP ppp;

The pppEvent() method is required for the implementation of pppEventListener. It takes a PPPEvent as an argument. The method itself consists simply of a switch statement that implements the PPP finite state machine that we discussed earlier in this chapter.

Each possible PPPEvent is handled by a case in the switch statement, and each of these corresponds to a state in our FSM. Note that we don’t do anything in the AUTHENTICATION_REQUEST state because as a client, we’re not going to be requesting authentication. The PPP server we’re calling will request it of us. So we don’t need to worry about this case.

public void pppEvent (PPPEvent e) {

switch(e.getEventType()) {

case PPPEvent.STARTING:

System.out.println(“PPP sent the STARTING event!”);

ppp.up(serialPort);

break;

case PPPEvent.UP:

System.out.println(“PPP sent the UP event!”);

ppp.addInterface(“ppp0”);

break;

case PPPEvent.AUTHENTICATION_REQUEST:

//We don’t have to do anything here, because

//We’re dialing out TO a server. break;

case PPPEvent.STOPPED: System.out.println(“Calling ppp.close()” ); ppp.close();

break;

case PPPEvent.CLOSED:

System.out.println(“PPP sent the CLOSED event!”);

ppp.down(); ppp.removeEventListener(this); serialPort.close(); System.exit(0);

break;

default:

System.out.println( “Some other ppp event happened” );

break;

}

}

The only other method in this class is the main() method. Our program takes the username, password, and AT command strings as arguments. We start by creating a

Modem object and a serialPort object. Then we create a PPPClient object, to act as a

pppEventListener.

public static void main(String[] args) {

String[] dialString=new String[(args.length)-2];

for (int i=0;i<(args.length)-2; i++) {

dialString[i]=args[i+2];

}

Modem external = new Modem(); external.openSerialPort(“serial0”); serialPort = external.serialPort; PPPClient ourListener = new PPPClient();

When we create the PPP object, the pppEventListener FSM is in the INIT state. We create two byte arrays that hold the local and remote IP addresses. The remote machine we are calling will provide those addresses.

ppp = new PPP();

byte[] localAddress = new byte[] {0, 0, 0, 0};

byte[] remoteAddress = new byte[] {0, 0, 0, 0};

This next section sets up parameters required to form a PPP connection. We add the event listener, and supply the username and password (stored in the first two command line arguments). These are the username and password used to login to the account we are dialing. We set authentication to false, meaning we don’t require the ISP to supply a username and password. It also means that we won’t go to the AUTHENTICATION_REQUEST state. Finally, we set the default interface to true, which means that our PPP interface will be the default IP interface on TINI.

try { ppp.addEventListener(ourListener); ppp.setLocalAddress(localAddress); ppp.setRemoteAddress(remoteAddress); ppp.setACCM(0×00000000); ppp.setAuthenticate(false); ppp.setUsername(args[0]); ppp.setPassword(args[1]); ppp.setDefaultInterface(true);

} catch(Exception e) { System.out.println(e);

System.out.println(“The ppp methods failed”);

serialPort.close(); System.exit(0);

}

Having set up the PPP parameters, we send the dial string of AT commands to the modem and wait for it to succeed. If it fails, we print some stuff, close the port, and exit. It if succeeds, we call the open() method and that will send us out of the INIT state in the pppEventListener FSM and starts the whole PPP connection process rolling.

if (external.dial(dialString)) {

ppp.open();

} else {

System.out.println(“The dialer failed!”);

serialPort.close(); System.exit(0);

}

while(true) {

//run forever…

}

}

Once the connection is established, this program loops forever. If you’re in a Telnet window, simply form a connection right over the top of this or close that Telnet window and open another one. In this new Telnet window, you can now access the Internet with FTP and ping. We’ve found that ping is sometimes unsuccessful in finding its IP target, when FTP works. You can run applications under Slush that communicate with the Internet and they will use the interface established by PPPClient. To stop PPPClient, you need to use the kill command. Let’s try running it.

Again, use a TINI connected to a PC via Ethernet. Connect the TINI to a modem via the specially made cross-over cable. To compile the program, create a separate folder and place PPPClient.java in it, as well as Modem.java. Make a bin folder in the same directory. Then type the following:

C:\> cd src

C:\> javac -bootclasspath %TINI_HOME%\bin\tiniclasses.jar

-d ..\bin PPPClient.java

C:\> cd ..

C:\> java -classpath %TINI_HOME%\bin\tini.jar;. BuildDependency

-p %TINI_HOME%\bin\owapi_dependencies_TINI.jar

-f bin

-x %TINI_HOME%\bin\owapi_dep.txt

-o bin\PPPClient.tini

-d %TINI_HOME%\bin\tini.db

As we’ve done in previous examples, some of the command line arguments for the java command have been shown on a separate line. Everything after java should be entered on the same line. Transfer the .tini file to your TINI stick via FTP, and via Telnet attempt the following as the root user:

TINI /> downserver -s

Warning:  This will disconnect users on specified servers.

OK to proceed? (Y/N): y

[ Wed Feb 20 00:13:05 GMT 2002 ]   Message from System: Serial server stopped.

TINI /> java PPPClient.tini <username> <password> AT ATM1L0

ATDT5555555555

Dialing … Sending: AT Receiving:

Sending: ATM1L0

Receiving: AT

OK ATM1L0

OK

Sending: ATDT5555555555

Receiving: ATDT5555555555

CONNECT 48000

PROTOCOL:LAPM

PPP sent the STARTING event! PPP sent the UP event!

Once you see the notice about the UP event, you have a connection. You can log in to the TINI stick with another Telnet session and try the following:

TINI /> ps

3 processes

1: Java GC (Owner root)

2: init (Owner root)

31: PPPClient.tini (Owner root)

TINI /> ipconfig -x Interface 0 is active. Name       : eth0

Type          : Ethernet

IP Address   : 192.168.0.5

Subnet Mask   : 255.255.255.0

Gateway       : 0.0.0.0

Interface 1 is active. Name      : lo

Type          : Local Loopback

IP Address   : 127.0.0.1

Subnet Mask  : 255.0.0.0

Gateway       : 0.0.0.0

Interface 2 is active.

Name          : ppp0 (default)

Type          : Point-to-Point Protocol

IP Address    : xxx.xxx.xx.xxx

Subnet Mask   : 255.255.255.0

Gateway       : 0.0.0.0

Interface 3 is not active. TINI />

There are several things to note about what we’ve just done. To start with, we need to be the root user to do this, and we always need to start by shutting  down the serial server with the downserver –s command, or, disable the server by modifying the etc/.startup file, with the line setenv SerialServer  disable. In the examples shown above, we’ve removed the real phone numbers, usernames, passwords, and IP addresses used. You need to use your own phone number, username, and password. (The username and password required by your ISP, not the ones you use on TINI.) Upon executing ipconfig –x  you will see that a new interface is now active and is the default. It’s ppp0, the interface we just added. The IP address shown for that (X’d out in this case) will actually be the IP address given to you by your ISP. You can go further with the ipconfig command and input a DNS IP address (provided by your ISP), and a mail host for the sendmail command (also provided by your ISP). To stop the PPPClient, you will have to use the kill command, and kill the PPPClient process.

What if things didn’t work for you? There are a number of things that can go wrong. You should power cycle the modem before running the program, make sure that any processes from previous PPPClient attempts are killed, always shut down the serial server (or disable it), and make sure your ISP supports PAP. You may also want to double check to see that the connection preferences of your ISP wants (data bits, parity, stop bits, flow control) match those being set in the program. With respect to compilation and TINIconvertor, always use a separate directory in which the only java files are PPPClient.java and Modem.java. Beyond this, if you’ve tested the dialing string with the previous examples but the PPP still doesn’t work, consider browsing the TINI archives on the web. There is a wealth of information about PPP out there. If everything above worked, but when you did the ipconfig –x  you did NOT see the ppp0 interface, try the last resort: clear the heap, reload the TINI firmware (tini.tbin, slush.tbin) and try again.

Random Posts

Comments are closed.