Wednesday, October 15, 2014

Send SMS using GSM Modem from Oracle Database

Send SMS using GSM Modem from Oracle Database

 SMSLib:

SMSLib provides a universal texting API, which can be used for sending and receiving messages via GSM modems.

Pre-requisites:

JDK 1.6 or higher
 JAVA Compiler

Configure SMSLib: You need the following files to configure SMSLib. You can find all of this file in Configuration_Files folder.

Download Files

Click the download link




1.       javax.comm.properties
2.       comm.jar
3.       RXTXcomm.jar
4.       win32com.dll
JAVA_HOME is path where jdk is installed

Step 1:- Copy comm.jar to
·         %JAVA_HOME%/lib  
[ In my case C:\Program Files\ Java\jdk1.7.0_03\lib ]
·         %JAVA_HOME%/jre/lib/ext
[ In my case C:\Program Files\ Java\jdk1.7.0_03\jre\lib\ext ]

Step 2:- Copy win32com.dll to
·         %JAVA_HOME%/bin
[In my case C:\Program Files\ Java\jdk1.7.0_03\bin ]
·         %JAVA_HOME%/jre/bin
      [ In my case C:\Program Files\ Java\jdk1.7.0_03\jre\bin ]
·         %windir%System32
             [ In my case C:\Windows\System32 ]

Step 3 : Copy javax.comm.properties to
·         %JAVA_HOME%/lib
            [ In my case C:\Program Files\ Java\jdk1.7.0_03\lib ]
·         %JAVA_HOME%/jre/lib
            [ In my case C:\Program Files\Java\jdk1.7.0_03\jre\lib ]
Step 4 : Copy RXTXcomm.jar to
·         %JAVA_HOME%/ jre/lib/ext
            [ In my case C:\Program Files\ Java\jdk1.7.0_03\lib ]

1.     Now open your NetBeans IDE

2.     You can find your modem port using CommunicationPortTest class. After finding port and bauds enter your port and bauds in SendSMS class. Please see red color line.

3.     Add the following jar files in your libraries (log4j-1.2.16.jar, ojdbc6.jar, smslib-3.5.1.jar)

4.     Create the following two class (SendSMS, DBCP)

5.     Create one table (SMS_LIST)

6.     Now insert row in SMS_LIST table and run project you can get SMS.

SendSMS Class


/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package smsgetway;
import org.smslib.AGateway;
import org.smslib.AGateway.GatewayStatuses;
import org.smslib.IOutboundMessageNotification;
import org.smslib.OutboundMessage;
import org.smslib.Service;
import org.smslib.modem.SerialModemGateway;
import java.sql.*;
/**
 *
 * @author rajib.pradhan
 */

public class SendSMS extends Thread {
    OutboundNotification outboundNotification;
    StringBuffer sql1;  
    SerialModemGateway gateway;
    String smsGatewayStatus = "";
    GatewayStatuses status;
    int i=0;
    public SendSMS() {
        try {
           
            outboundNotification = new OutboundNotification();
            SerialModemGateway gateway = new SerialModemGateway("modem.COM27", "COM27", 9600, "", "");
            gateway.setInbound(true);
            gateway.setOutbound(true);
            Service.getInstance().setOutboundMessageNotification(outboundNotification);
            Service.getInstance().addGateway(gateway);
            Service.getInstance().startService();
            status = gateway.getStatus();
            smsGatewayStatus = status.toString();
        } catch (Exception e) {
            System.out.println("EXCEPTION gateway.getStatus : "+gateway.getStatus());
            status = gateway.getStatus();
            smsGatewayStatus = status.toString();
            e.printStackTrace();
            System.out.println("Exception e.getMessage: " + e.getMessage());
            System.out.println("Exception cause: " + e.getCause());
        }
    }

    public void sendSMStoMobile() throws Exception {
        if (smsGatewayStatus.equals("STOPPED")) {
            return;
        }

        DBCP dbcp = DBCP.getInstance();
        Connection connection = dbcp.getConnection();
        Statement statement = connection.createStatement();
        ResultSet resultSet = null;
       
        try {
            sql1 = new StringBuffer();
            sql1.append("SELECT MOBILE_NUMBER, MESSAGE, TRANUM ");
            sql1.append("FROM SMSGATEWAY.SMS_LIST ");
            sql1.append("WHERE SEND_STATUS = 'N' ");
            resultSet = statement.executeQuery(sql1.toString());
           
            while (resultSet.next()) {
              
                String destMobileNo = resultSet.getString(1);
                System.out.println("Phone Number "+resultSet.getString(1));
                String message = resultSet.getString(2);
                String tranNumber = resultSet.getString(3);
                OutboundMessage sms = new OutboundMessage(destMobileNo, message);
                Service.getInstance().sendMessage(sms);
                //Update Table After Send Message
                String updateQuery = "UPDATE SMSGATEWAY.SMS_LIST SET SEND_STATUS = 'Y' WHERE TRANUM = " + tranNumber ;
                if(i<20)
                {
               System.out.print(tranNumber+": Y, ");
               
                }
                if(i==20){
                System.out.print(tranNumber+": Y, "+"\n");
                i=0;
                }
                statement.executeUpdate(updateQuery);
                connection.commit();
                i=i+1;
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (resultSet != null) {
                resultSet.close();
            }
            if (statement != null) {
                statement.close();
            }
            dbcp.releaseConnection(connection);
        }
    }

    public class OutboundNotification implements IOutboundMessageNotification {

        public void process(AGateway gateway, OutboundMessage msg) {
            System.out.println(msg);
        }
    }

    public void run() {
        while (true) {
            try {
                sendSMStoMobile();
                this.sleep(1000);
            } catch (Exception e) {
            }
        }
    }

    public static void main(String[] args) throws Exception {
        SendSMS sendSMSFromDB = new SendSMS();
        sendSMSFromDB.start();
    }

    private void getModemInformation(SerialModemGateway gateway) throws Exception{
        System.out.println();
        System.out.println("Modem Information:");
       
        System.out.println("  Model: " + gateway.getModel());
        System.out.println("  Serial No: " + gateway.getSerialNo());
        System.out.println("  SIM IMSI: " + gateway.getImsi());
        System.out.println("  Signal Level: " + gateway.getSignalLevel() + " dBm");
        System.out.println("  Battery Level: " + gateway.getBatteryLevel() + "%");
        System.out.println("  Manufacturer: " + gateway.getManufacturer());
        System.out.println();
    }
}

Database Connection (DBCP) Class


/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package smsgetway;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.Vector;
import java.util.Stack;

/**
 *
 * @author rajib.pradhan
 */
/*
 *
 * Database Connection Information
 *
 */

public class DBCP implements Runnable {

    private static DBCP connectionPool;
    private Stack pool;
    private Vector busyConnections;
    private int MAX_CONNECTIONS = 10000;
    private int MIN_CONNECTIONS = 1;
    private long timeout;
    private String sDriver;
    private String sDBUrl;
    private String sUsername;
    private String sPassword;

    private DBCP(String sDriver,
                 String sUrl,
                 String sUserName,
                 String sPassword,
                 int sMaxConnection,
                 int sMinConnection,
                 long sTimeOut) throws SQLException {
       
        this.timeout = sTimeOut;
        this.sDriver = sDriver;
        this.sDBUrl = sUrl;
        this.sUsername = sUserName;
        this.sPassword = sPassword;
        this.MAX_CONNECTIONS = sMaxConnection;
        this.MIN_CONNECTIONS = sMinConnection;
        busyConnections = new Vector();
        pool = new Stack();
        for (int i = 0; i < MIN_CONNECTIONS; i++) {
            pool.push(makeNewConnection());
        }
    }

    public static DBCP getInstance() {
        if (connectionPool == null) {
            try {
                connectionPool =
                        new DBCP(
                        "oracle.jdbc.OracleDriver",
                       "jdbc:oracle:thin:@localhost:1521:ORCL",
                        "SMSGATEWAY",
                        "SMSGATEWAY",
                        10,
                        5,
                        30000);
            } catch (SQLException _sqlex) {
                _sqlex.printStackTrace();
            }
        }
        return connectionPool;
    }

    public synchronized Connection getConnection() throws SQLException, InterruptedException {
        Connection connection = null;
        if (connectionPool != null) {
            if (pool.size() != 0) {
                connection = (Connection) pool.pop();
                busyConnections.add(connection);
            } else {
                if (getTotalConnections() >= MAX_CONNECTIONS) {
                    while (busyConnections.size() < MAX_CONNECTIONS) {
                        connection = (Connection) pool.pop();
                        if (connection != null) {
                            connection.close();
                        }
                    }
                } else {
                    makeBackgroundConnection();
                    wait();
                    connection = getConnection();
                }
            }
        }
        return connection;
    }

    protected int getTotalConnections() {
        return pool.size() + busyConnections.size();
    }

    private void makeBackgroundConnection() throws SQLException {
        try {
            Thread connectionThread = new Thread(this);
            connectionThread.start();
        } catch (Exception _ex) {
            throw new SQLException("Max Limit of connections exceeded");
        }
    }

    private synchronized Connection makeNewConnection() throws SQLException {
        try {
            Class.forName(sDriver);
            Connection connection =
                    DriverManager.getConnection(sDBUrl, sUsername, sPassword);
            connection.setAutoCommit(false);
            return connection;
        } catch (ClassNotFoundException cnfe) {
            throw new SQLException("Can't find class for driver: " + sDriver);
        }
    }

    /**
     * run() function for making a new connection from the
     * backgroud called by makeBackgroundConnection()
     */
    public void run() {
        synchronized (this) {
            try {
                Connection con = makeNewConnection();
                pool.push(con);
                notifyAll();
            } catch (Exception _ex) {
            }
        }
    }

    /**
     *
     * @return Information about this connection pool
     */
    public synchronized void releaseConnection(Connection con) {
        pool.push(con);
        busyConnections.remove(con);
        notifyAll();
    }

    public synchronized String toString() {
        String info =
                "ConnectionPool("
                + sDBUrl
                + ","
                + sUsername
                + ")"
                + ", available="
                + pool.size()
                + ", busy="
                + busyConnections.size()
                + ", max="
                + MAX_CONNECTIONS;
        return info;
    }

    /**
     *
     * @throws SQLException
     */
    private synchronized void closeAllConnections() throws SQLException {
        while (!pool.isEmpty()) {
            try {
                ((Connection) pool.pop()).close();
            } catch (Exception _ex) {
                throw new SQLException("Unable to close the Connection");
            }
        }
        pool = new Stack();
        for (int i = 0; i < busyConnections.size(); i++) {
            try {
                ((Connection) busyConnections.get(i)).close();
                busyConnections.remove(i);
            } catch (Exception _ex) {
                throw new SQLException("Unable to close the Connection");
            }
        }
        busyConnections = new Vector();
    }

    /**
     *
     * @throws java.lang.Throwable
     */
    protected void finalize() throws java.lang.Throwable {
        try {
            closeAllConnections();
        } catch (Exception _ex) {
        }
        super.finalize();
    }
}

Port finding class (CommunicationPortTest.class)

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package smsgetway;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Enumeration;
import java.util.Formatter;
import javax.swing.JDialog;
import javax.swing.JOptionPane;
import org.smslib.helper.CommPortIdentifier;
import org.smslib.helper.SerialPort;

/**
 *
 * @author rajib.pradhan
 */

public class CommunicationPortTest {

    private static final String _NO_DEVICE_FOUND = "No Device Found.";
    private final static Formatter _formatter = new Formatter(System.out);
    static CommPortIdentifier portId;
    static Enumeration<CommPortIdentifier> portList;
    static int bauds[] = {9600, 14400, 19200, 28800, 33600, 38400, 56000, 57600, 115200};

    /**
     * Wrapper around {@link CommPortIdentifier#getPortIdentifiers()} to be
     * avoid unchecked warnings.
     */
    private static Enumeration<CommPortIdentifier> getCleanPortIdentifiers() {
        return CommPortIdentifier.getPortIdentifiers();
    }

    public static void main(String[] args) {
        System.out.println("\nSearching for devices...");
        portList = getCleanPortIdentifiers();
        while (portList.hasMoreElements()) {
            portId = portList.nextElement();
            if (portId.getPortType() == CommPortIdentifier.PORT_SERIAL) {
                _formatter.format("%nFound port: %-5s%n", portId.getName());
                for (int i = 0; i < bauds.length; i++) {
                    SerialPort serialPort = null;
                    _formatter.format("       Trying at %6d...", bauds[i]);
                    try {
                        InputStream inStream;
                        OutputStream outStream;
                        int c;
                        String response;
                        //serialPort = portId.open("SMSLibCommTester", 1971);
                        serialPort = portId.open("SMSAPP", 1971);
                        serialPort.setFlowControlMode(SerialPort.FLOWCONTROL_RTSCTS_IN);
                        serialPort.setSerialPortParams(bauds[i], SerialPort.DATABITS_8, SerialPort.STOPBITS_1, SerialPort.PARITY_NONE);
                        inStream = serialPort.getInputStream();
                        outStream = serialPort.getOutputStream();
                        serialPort.enableReceiveTimeout(1000);
                        c = inStream.read();
                        while (c != -1) {
                            c = inStream.read();
                        }
                        outStream.write('A');
                        outStream.write('T');
                        outStream.write('\r');
                        Thread.sleep(1000);
                        response = "";
                        StringBuilder sb = new StringBuilder();
                        c = inStream.read();
                        while (c != -1) {
                            sb.append((char) c);
                            c = inStream.read();
                        }
                        response = sb.toString();
                        if (response.indexOf("OK") >= 0) {
                            try {
                                System.out.print("  Getting Info...");
                                outStream.write('A');
                                outStream.write('T');
                                outStream.write('+');
                                outStream.write('C');
                                outStream.write('G');
                                outStream.write('M');
                                outStream.write('M');
                                outStream.write('\r');
                                response = "";
                                c = inStream.read();
                                while (c != -1) {
                                    response += (char) c;
                                    c = inStream.read();
                                }
                                System.out.println(" Found: " + response.replaceAll("\\s+OK\\s+", "").replaceAll("\n", "").replaceAll("\r", ""));
//                                JOptionPane.showMessageDialog(null," Found: " + response.replaceAll("\\s+OK\\s+", "").replaceAll("\n", "").replaceAll("\r", ""), "Warning",
//                                JOptionPane.WARNING_MESSAGE);
                            } catch (Exception e) {
                                System.out.println(_NO_DEVICE_FOUND);
//                                JOptionPane.showMessageDialog(null, _NO_DEVICE_FOUND, "Warning",
//                                JOptionPane.WARNING_MESSAGE);
                            }
                        } else {
                            System.out.println(_NO_DEVICE_FOUND);
//                            JOptionPane.showMessageDialog(null, _NO_DEVICE_FOUND, "Warning",
//                                JOptionPane.WARNING_MESSAGE);
                        }
                    } catch (Exception e) {
                        System.out.print(_NO_DEVICE_FOUND);
//                        JOptionPane.showMessageDialog(null, _NO_DEVICE_FOUND, "Warning",
//                                JOptionPane.WARNING_MESSAGE);
                        Throwable cause = e;
                        while (cause.getCause() != null) {
                            cause = cause.getCause();
                        }
                        System.out.println(" (" + cause.getMessage() + ")");
                    } finally {
                        if (serialPort != null) {
                            serialPort.close();
                        }
                    }
                }
            }
        }
        System.out.println("\nCommunication Test Completed.");
//        JOptionPane.showMessageDialog(null, "Communication Test Completed.", "Information",
//                                JOptionPane.INFORMATION_MESSAGE);
    }
}

Table Scripts

CREATE TABLE SMS_LIST
(
  MOBILE_NUMBER  VARCHAR2(20 BYTE),
  MESSAGE        VARCHAR2(300 BYTE),
  SEND_STATUS    CHAR(1 BYTE)                   DEFAULT 'N',
  TRANUM         VARCHAR2(30 BYTE)
)


8 comments:

  1. Hi. Thank you for your program code.
    I have succeed test it on my test server.
    However there something that i cannot understand.
    1. If table sms_list have no record, it cannot work
    2. what doean "TRANUM" column do ?
    3. what does variable 'i" do ? for printout System.out.print(tranNumber+": Y, ") 20 times ?

    ReplyDelete
    Replies
    1. Hello Dear,

      1. It will work but no SMS will send to user/customer, because from sms_list table collect all of phone number and text to send SMS.

      2. "TRANUM" This column contain Unique number to ensure that SMS are send successfully and One SMS will send to customer only one time.

      3. I can't Understood Your Last Question.

      Thank You.

      Delete
  2. This comment has been removed by the author.

    ReplyDelete
  3. Where I create step 4,Step 5.I want to connect with oracle apex. Is it possible?

    ReplyDelete
  4. It will send SMS from Java layer. You have to use JDK 1.6 or higher
    JAVA Compiler.

    ReplyDelete
  5. This blog is nice and interesting. Thanks for sharing those information it is really well and good. Java SMS Script

    ReplyDelete
  6. Dear brother downloading link not properly work

    ReplyDelete