Java and YAC: Take Caller ID Beyond the Phone and into the Network

he Calling Number Delivery (CND) service, commonly known as caller ID, allows phone users who have caller ID-compatible equipment to receive identification information about incoming calls, including the calling party’s directory number, the calling party’s name, and the date and time of the call.

Many modems on the market today offer caller ID support, allowing a computer to consume caller ID information just like a phone or caller ID box might. In the Java world, the Java Telephony API (JTAPI) was meant to process caller ID information, as well as address other telephony-related programmatic needs. Unfortunately, the JTAPI documentation for consuming caller ID information is practically non-existent.

 
Figure 1. YAC Residing in the Tray Notification Area

While trying to figure out how to accomplish this task, I came across a Windows program named YAC, a software-based caller ID system that makes consumption of caller ID information using Java?and virtually any other programming language via which you can listen to sockets?straightforward.

YAC stands for “Yet Another Caller ID Program.” Jensen Harris wrote the source code in C++, and he distributes it under the GNU General Public License. This tutorial uses YAC to send caller ID information to a Java consumer and then leverages the JavaMail API to distribute the information to users via email. Fortunately, you don’t have to use the Java Native Interface (JNI) to do this, as YAC allows you to consume caller ID data via sockets.

Screen Calls on Your PC

Go ahead and download YAC. Look for the download labeled “YAC for Windows (includes Server and Listener)”. At the time of this article’s writing, YAC was in version 0.16.

 
Figure 2. YAC Notifying Listeners of Incoming Calls and Their Caller ID Information

To report caller ID information, YAC requires that you have a caller ID-compatible modem installed and that you are subscribed to receive caller ID information from your telephone service provider. YAC uses a client/server setup to notify “YAC Listeners” on a network about incoming calls. So with the YAC server installed on a machine with a caller ID modem, you can send caller ID information received to registered YAC clients. I personally use YAC to send caller ID information to my laptop wirelessly, so I can screen my calls (my place is usually too much of a mess to find the phone and see who is calling!).

If you are interested in simply having a Windows program that displays caller ID information, YAC works great. Simply unzip the YAC zip file you downloaded and run the setup program. The setup is pretty straightforward. Upon your first invocation of YAC, you will be asked to choose the modem to which YAC will listen. After that, YAC places an icon in your tray notification area (see Figure 1).

YAC sits in your tray notification area and acts as a daemon, waiting for incoming calls. When you receive a call, you should see a notification reporting the caller ID information (see Figure 2).

Of course, this article is about consuming caller ID information via Java. So let’s get back to that.

Making YAC Send Caller ID Information to Listeners

Before you start coding in Java, you must set up your YAC Server to send socket messages containing caller ID information. The YAC Server can send messages to the machine it resides on (i.e., the server) or to different machines in your network (i.e., clients). In either case, you have to register the clients/listeners YAC will send caller ID information to. To do this, right click on the YAC icon in your task notification area and select the Listeners… option (see Figure 3).

 
Figure 3. Choosing the Listeners Context Menu Option

In the subsequent Select listeners window, specify the hostname or IP address of the machines in your network that you want to process caller ID information. If you just want to process caller ID information on the server itself, just enter the IP address of your YAC server machine and click OK (see Figure 4).

Using the YAC Software Developer’s Kit

The YAC Software Developer’s Kit shows how you can create a YAC listener that can consume caller ID information sent by the YAC server to registered IP addresses (as done in the previous step section). YAC listeners listen on TCP port 10629 by default (a configurable option).

The YAC Software Developer’s Kit specifies that a client should listen for an incoming connection and then copy all sent text into a buffer until it receives either a null character (i.e., ‘O’) or 300 characters. The listener should then close the connection and do whatever it desires with the caller ID information it received.

The YAC Software Developer’s Kit specifies a typical caller ID buffer as follows:

@CALLBush George W.~(212) 555-9384
 
Figure 4. Specifying YAC Listener Connection Information

With this information, you are now ready to start coding a Java client that will listen for caller ID information as reported via a YAC server.

Creating a Java (Socket) Listener

You can find the code for your Java-based YAC Listener in the class YACListener.java. The first thing to do in the code is create a java.net.ServerSocket, which is bound to the YAC port, 10629:

ServerSocket serverSocket = new ServerSocket(port);

Next, in a while loop, listen for an incoming connection to the socket and accept it with the line:

Socket socket = serverSocket.accept();

Consume the data the YAC server sends with the syntax below, which grabs an input stream for the socket and binds it to a BufferedReader object:

BufferedReader input = new BufferedReader(new InputStreamReader(socket.getInputStream()));

To report your caller ID payload to your client, use another while loop, which listens and breaks if your input is null and outputs to the console if it isn’t:

// print received callerID datawhile (true){	String message = input.readLine();	if (message == null)		break;	System.out.println(message);}

Once a null message is received, you close your socket connection:

socket.close();

Then, go back to listening for more incoming YAC messages.

Using JavaMail for Email Caller ID Notification

So far, you have simply reported the caller ID information payload you receive to the console using System.out. Using the JavaMail API, you can send the caller ID information you receive to a specified email address. (If you are unfamiliar with the JavaMail API, take a look at JGuru’s Fundamentals of the JavaMail API short course.) To be able to send mail using the JavaMail API, you must have the JARs of the JavaMail API, as well as the Java Beans Activation Framework, in your classpath.

To get the YACListener class to send out an email for received caller ID information, you need to specify the following settings at the beginning of the class:

  • Your SMTP server info
  • The email address that you want to be the sender of your caller ID info (which your SMTP server allows to send mail out)
  • The address of who you want to receive the caller ID email

The beginning of your class will look like the following example:

static String SMTPSERVER = "smtp.austin.ibm.com";static String MAILSENDERADDRESS = "[email protected]";static String MAILRECIPIENTADDRESS = "[email protected]";

The static sendMail method sends out your email. The following is the core processing logic for this method:

Properties props = System.getProperties();props.put("mail.smtp.host", SMTPSERVER);Session session = Session.getDefaultInstance(props, null);// -- Create a new message --Message message = new MimeMessage(session);// -- Set the FROM and TO fields --message.setFrom(new InternetAddress(MAILSENDERADDRESS));message.setRecipients(Message.RecipientType.TO, InternetAddress.parse(MAILRECIPIENTADDRESS, false));// -- Set the subject and body text --String subject = "Caller ID info received from YAC";message.setSubject(subject);String body = yacPayLoad;message.setText(body);message.setSentDate(new Date());// -- Send the message --Transport.send(message);System.out.println("Message sent OK.");

To summarize, you create a javax.mail.Session using a Properties object populated with your SMTP server information. Using the Session, you create a javax.mail.Message object, to which you associate your sender and recipient email addresses, using the setFrom and setRecipients methods respectively. Using the setSubject method, you set the subject of the Message to the String: “Caller ID info received from YAC”. Next, you set the body of your Message object to the message that was sent from the YAC server. It is this message that contains your caller ID information. Finally, you send the message using the following call:

Transport.send(message);

Using JavaMail for Text Messaging Caller ID Notification

In addition to sending your caller ID information via email, wouldn’t sending it to your cell phone via text messages be nice? This operation would typically require a third-party SMS gateway, but alternatively you could send text messages via e-mail, a service many cell phone providers offer. For example, to send a text message to a Sprint PCS phone, you can send an email to 8155551234 @messaging.sprintpcs.com if your Sprint PCS cell phone number is (815) 555-1234. Accordingly, to send messages via the YACListener.java class, simply replace the MAILRECIPIENTADDRESS static String with the email address corresponding to your desired cell phone number destination. Most cell phone providers in the U.S. provide an email address to cell phone mapping. You might also want to take a look at Teleflip, a free service that delivers text messages to cell phones.

Provide Caller ID Information via Sockets

This article demonstrated how to use YAC, an open-source Windows application that uses a client/server model to provide caller ID information via sockets. It showed how to consume the caller ID information via the Java programming language and leverage the JavaMail API to send caller ID information via e-mail.

Share the Post:
Share on facebook
Share on twitter
Share on linkedin

Overview

Recent Articles: