Thursday 8 August 2013

How to send and receive mobile SMS in java



Here i will show you.  How we can send and receive mobile SMS in core java
   
I have been also applied this code for sending and receiving mobile SMS. It has been successfully working. you can also apply this code. please follow some steps given below.

Requirements:

1) jdk 1.6
2) comm jar         // It is use for communicating serial ports java
3) javax.comm.properties 
4) log4j-1.2.8.jar
5) win32com.dll    // for windows Operating System 

Create class files

1) ComputeSmsData
2) SerialToGsm

If you are using Eclipse IDE. So you can see the structure of application

 
 --------------------------- ComputeSmsData.java -----------------------------


import java.io.*;
import java.sql.SQLException;
import java.util.BitSet;
import javax.comm.*;

public class ComputeSmsData {
    
    private String telNum;
    private String telNumSMSC;
    private String telNumLen;
    private String telNumSMSCLen;
    private String pduTxt;
    private String pduTxtLen;

    private String rcvdPdu;
    private String rcvdSMSC;
    private String rcvdSenderNum;
    private String rcvdPduTxt;


     public static void main(String ar[]){
     //GetData GT = new GetData();
    try{
         //ComputeSmsData sms = new ComputeSmsData();
        //SerialToGsm stg = new SerialToGsm("serial0");
        SerialToGsm stg = new SerialToGsm("COM7");
        System.out.println(stg);

        String retStr = new String("");
        String sss = new String();
        String alarmNumber = new String("+910000000000");   // a real phone number here
    
        System.out.println(stg.readSms());
        System.out.println(stg.checkSms());
        //InsertDB insertdb = new InsertDB("");
        //insertdb.datainsert();
          // check for messages
        retStr = stg.checkSms();
        if (retStr.indexOf("ERROR") == -1) {
        //GT.datainsert(stg.readSmsSender(),stg.readSms());
            System.out.println("Phone # of sender: " + stg.readSmsSender());//Sender phone id
            System.out.println("Recv'd SMS message: " + stg.readSms()+"---Aman Test---");//sender number
        }
        

        // send a message
        //sss = stg.sendSms(alarmNumber,"Hello GSM World");
    }
    catch (Exception e){
    e.printStackTrace();
    }
     }   
        
    
    //*********************************************************************
    //                              encode text message in 7bit GSM standard
    //*********************************************************************      
    
    private void txtToSmsPdu(String testo) {
        // first of all set the msg lenght
        pduTxtLen = Integer.toHexString(testo.length());
        
        if (pduTxtLen.length() < 2) {
            pduTxtLen = "0" + pduTxtLen;
        }
        pduTxtLen = pduTxtLen.toUpperCase();
        
//        System.out.println("testo da convertire <" + testo + ">");

        byte[] ccc = testo.getBytes(); // get ASCII(?) bytes value

        BitSet bs = new BitSet(testo.length() * 8);
        int l = 0; 

        for (int i = 0; i < testo.length(); i++) {
            for (int subI = 0; subI < 7; subI++) {
                l = i * 7 + subI;
                if ((ccc[i] & (1 << subI)) != 0) {
                    bs.set(l);
                }
            }
        }
        l++;
//        System.out.println("Elle = " + l);

        int ll;
        
        // check if size fit a byte
        if (((l / 56) * 56) != l) { // 56 = 7*8 = M.C.M.
            ll = (l / 8) + 1;
        }
        else {
            ll = l / 8;
        }
if (ll == 0) {
ll++;
}
  
//        System.out.println("Elle2 = " + ll);
  
        byte[] b = new byte[ll];
        for (int i = 0; i < ll; i++) {
            for (int subI = 0; subI < 8; subI++) {
                if ((l + 1) > (i * 8 + subI)) {  // should be less then last 1 in bs
                    if (bs.get(i * 8 + subI)) {
                        b[i] |= (byte)(1 << subI);
                    }
                }
            }
        }

        pduTxt = new String("");
        for (int i = 0; i < ll; i++)
        {
            String str1 = Integer.toHexString((int)b[i]);   // convert # in string
            if (str1.length() < 2) {
                str1 = '0' + str1;
            }
            str1 = (str1.substring(str1.length()-2,str1.length()));
            pduTxt += str1.toUpperCase();
        }
        
        System.out.println("Stringa convertita   <" + pduTxt + ">");
        System.out.println("Stringa riconvertita <" + smsPduToTxt(pduTxt) + ">");
        System.out.println(getRcvdPduSMSC());
    }


    // ******************************
    // set text message (from extern)
    // ******************************
    public void setAsciiTxt(String s) {
        txtToSmsPdu(s);
    }


    // *********************************************************
    // Encode destination telephone number in GSM stadard format
    // *********************************************************
    // str MUST be in international format
    private String encodeTelNum(String str) {

        // remove trailing '+' if any
        if (str.charAt(0) == '+') {
            str = str.substring(1, str.length());
        }                          
        
        // check if num length is even or odd
        int l = str.length();
        if (((l / 2) * 2) != l) {
            str += 'F';
            l++;
        }
        
        String tmpStr = new String();
        // swap chars
        for (int cnt = 0; cnt < (l / 2); cnt++) {
            tmpStr += str.charAt(cnt * 2 + 1);
            tmpStr += str.charAt(cnt * 2);
        }

        return tmpStr;
    }

    // *********************************************************
    // Encode destination telephone number in GSM stadard format
    // *********************************************************
    // str MUST be in international format
    private String encodeTelNumLen(String str) {
        String numLen = new String();

        // remove trailing '+' if any
        if (str.charAt(0) == '+') {
            str = str.substring(1, str.length());
        }                          
        
        // check if num length is even or odd
        int l = str.length();
        numLen = new String(Integer.toHexString(l));
        if (numLen.length() < 2) {
            numLen = "0" + numLen.toUpperCase();
        }                               
        return numLen;
    }

    // **********************************
    // set telephone number (from extern)
    // **********************************
    // WARNING: telephone number must be in international format
    // with or without leading '+'
    public void setTelNum(String s) {
        telNum    = encodeTelNum(s);
        telNumLen = encodeTelNumLen(s);
    }

    public void setSMSCTelNum(String s) {
        telNumSMSC = encodeTelNum(s);
        telNumSMSCLen = encodeTelNumLen(s);
    }

    public String getCompletePduData () {
        String pduData = new String();
        pduData = "11";                 // first octet of SMS Submit
        pduData += "00";                // let telephone set msg reference
        pduData += telNumLen;           // tel # length
        pduData += "91";                // tel # is int'l format
        pduData += telNum;              // tel Num in GSM format
        pduData += "00";                // protocol identifier TP-PID
        pduData += "00";                // pdu data is encoded 7bit data
        pduData += "AA";                // TP validity period
        pduData += pduTxtLen;           // length of text data
        pduData += pduTxt;              // message encoded data
                         
        return pduData;                         
    }

    public String getSMSCPduData () {
        String pduData = new String();
        pduData = telNumSMSCLen;           // tel # length
        pduData += "91";                // tel # is int'l format
        pduData += telNumSMSC;              // tel Num in GSM format
                         
        return pduData;                         
    }


    //**********************************************************************
    //                                         decode recv'd message
    //**********************************************************************  

    // ************************
    // set received Pdu from ME
    // ************************
    public void setRcvdPdu(String s) {                                                       
        rcvdPdu = s;
        computeRcvdPdu(rcvdPdu);
    }

    // **************************************
    // get received number of services center
    // **************************************
    public String getRcvdPduSMSC() {
        return rcvdSMSC;
    }

    // *****************
    // get sender number
    // *****************
    public String getRcvdSenderNumber() {
        return rcvdSenderNum;
    }

    // ********************
    // get received message
    // ********************
    public String getRcvdPduTxt() {
        return rcvdPduTxt;
    }

    // ***********************
    // decode rcvd Pdu message
    // ***********************
    private void computeRcvdPdu(String s) {               
        
        Integer lenOfSMSC = new Integer(Integer.parseInt(s.substring(0,2),16));

//        System.out.println("Len SMSC = " + lenOfSMSC.intValue());
//        System.out.println("SMSC info = " + s.substring(2,2+(lenOfSMSC.intValue() * 2)));
        
        // compute SMSC infos
        // ------------------
        rcvdSMSC = new String();
        rcvdSMSC = s.substring(2,4);    // add type of address (future evaluation?)
        rcvdSMSC += '.';                // add a separator
        // decode SMSC number and add to string
        rcvdSMSC += decodeTelNum(s.substring(4,4+((lenOfSMSC.intValue() - 1) * 2)));
//        System.out.println("dec'd SMSC info = " + rcvdSMSC);

        // remove part of message just evaluated                                                                                                 
        int lenOfRemovedTxt = 2 + (lenOfSMSC.intValue() * 2);
        s = s.substring(lenOfRemovedTxt , s.length());
        
        // remove first octet of SMS-DELIVER msg (future evaluation!)
        lenOfRemovedTxt = 2;
        s = s.substring(lenOfRemovedTxt , s.length());
//        System.out.println("Rimane da elaborare " + s);

        // evaluate sender address length
        Integer lenOfSenderNum = new Integer(Integer.parseInt(s.substring(0,2),16));

        rcvdSenderNum = new String("");
/*
remove comments to this part if you need to know type of address
        rcvdSenderNum = s.substring(2,4);    // add type of address (future evaluation?)
        rcvdSenderNum += '.';                // add a separator
*/
        // decode SMSC number and add to string
//        System.out.println(lenOfSenderNum.intValue());
        int tmpLenOfSender = lenOfSenderNum.intValue();
        if ((tmpLenOfSender / 2 * 2) != tmpLenOfSender) {
            tmpLenOfSender++;
        }
        rcvdSenderNum += decodeTelNum(s.substring(4,4+tmpLenOfSender));
//        System.out.println("dec'd Sender info = " + rcvdSenderNum);

        // remove computed text        
        tmpLenOfSender += 4;
        s = s.substring(tmpLenOfSender , s.length());
        
        // remove TP-ID (2 octet) (future evaluation?)
        lenOfRemovedTxt = 2;
        s = s.substring(lenOfRemovedTxt , s.length());
        // remove TP-DCS (2 octet) (future evaluation?)        
        lenOfRemovedTxt = 2;
        s = s.substring(lenOfRemovedTxt , s.length());
        // remove Time stamp (14 octet) (future evaluation?)        
        lenOfRemovedTxt = 14;                                     
        s = s.substring(lenOfRemovedTxt , s.length());
        // remove length of pdu data
        lenOfRemovedTxt = 2;                                     
        s = s.substring(lenOfRemovedTxt , s.length());

        rcvdPduTxt = smsPduToTxt(s);
    }



    // *****************
    // decode tel number
    // *****************
    private String decodeTelNum(String s) {
        String decodedStr = new String();
                                        
        for (int i = 0; i < (s.length() / 2); i++) {
            decodedStr += s.charAt(i * 2 + 1);
            decodedStr += s.charAt(i * 2);    
        }                                
        
        if (decodedStr.charAt(decodedStr.length() - 1) == 'F') {
            decodedStr = decodedStr.substring(0,decodedStr.length()-1);
        }

        return decodedStr;
    }                                                                                                    
                                                                                                    
    // ********************************
    // decode pdu text from 7bit format
    // ********************************
    private String smsPduToTxt(String s) {
        byte[] bt = new byte[s.length() / 2];
        for (int i = 0; i < (s.length() / 2); i++) {
            bt[i] = (byte)(Integer.parseInt(s.substring(i*2,i*2+1),16) * 16);
            bt[i] += (byte)Integer.parseInt(s.substring(i*2+1,i*2+2),16);
        }

        BitSet bs = new BitSet(s.length() / 2 * 8);
        int l = 0;

        for (int i = 0; i < (s.length() / 2); i++) {
            for (int subI = 0; subI < 8; subI++) {
                l = i * 8 + subI;
                if ((bt[i] & (1 << subI)) != 0) {
                    bs.set(l);
                }
            }
        }
        l++;
        
//        System.out.println("bit totali (8) " + l);

        int ll;
        // now we have to find the real septets
// this will miss 7 and 8 multiples (fixed at the
// end of this method looking for byte == 0)
// this is part A
// look at part B (at the end of the method)
  ll = (l / 7);
if (ll == 0) {
ll++;
}

//        System.out.println("bit totali (7) " + ll);
        
        byte[] b = new byte[ll];
        for (int i = 0; i < ll; i++) {
            for (int subI = 0; subI < 7; subI++) {
                if ((l + 1) > (i * 7 + subI)) {  // should be less then last 1 in bs
                    if (bs.get(i * 7 + subI)) {
                        b[i] |= (byte)(1 << subI);    
                    }
                }
            }
        }

// this is part B
// look at part A (at the middle of the method)
if (b[ll-1] == 0) {
       return (new String(b,0,ll-1)); // if last byte == 0 skip it
}
else {
        return (new String(b));
        }
    }
}


------------------------------- SerialToGsm.java -----------------------------------



import java.io.*;
import java.util.BitSet;
import javax.comm.*;
import java.lang.*;
  
public class SerialToGsm extends ComputeSmsData  {

    InputStream in;
    OutputStream out;
    String lastIndexRead;
    String senderNum;
    String smsMsg;

 
    SerialToGsm(String porta) {
        try {
//            CommPortIdentifier portId = CommPortIdentifier.getPortIdentifier("serial0");
            CommPortIdentifier portId = CommPortIdentifier.getPortIdentifier(porta);
            //SerialPort sp = (SerialPort)portId.open("Sms_GSM", 0);
            SerialPort sp = (SerialPort)portId.open("COM7", 0);
            sp.setSerialPortParams(9600, SerialPort.DATABITS_8, SerialPort.STOPBITS_1, SerialPort.PARITY_NONE);
            sp.setFlowControlMode(sp.FLOWCONTROL_NONE);

 
            in = sp.getInputStream();
            out = sp.getOutputStream();

 
            // modem reset
            sendAndRecv("+++AT", 30);       // delay for 20 sec/10
            sendAndRecv("AT&F", 30);
            sendAndRecv("ATE0", 30);        // echo off
            sendAndRecv("AT +CMEE=1", 30);  // verbose error messages
            sendAndRecv("AT+CMGF=0", 70);   // set pdu mode
//            sendAndRecv("AT V1E0S0=0&D2&C1", 1000000);

 
        }
        catch (Exception e) {
            System.out.println("Exception " + e);
    System.exit(1);
        }
    }

 
    private String sendAndRecv(String s, int timeout) {
        try {
            // clean serial port input buffer
            in.skip(in.available());
            System.out.println("=> " + s);
            s = s + "\r";         // add CR
            out.write(s.getBytes());
            out.flush();            
            
            String strIn = new String();
            for (int i = 0; i < timeout; i++){
                int numChars = in.available();
                if (numChars > 0) {
                    byte[] bb = new byte[numChars];
                    in.read(bb,0,numChars);
                    strIn += new String(bb);
                }
                // start exit conditions
                // ---------------------
                if (strIn.indexOf(">\r\n") != -1) {
                    break;
                }                                         
                
                if (strIn.indexOf("OK\r\n") != -1){
                    break;
                }                                         
                
                if (strIn.indexOf("ERROR") != -1) { // if find 'error' wait for CR+LF
                    if (strIn.indexOf("\r\n",strIn.indexOf("ERROR") + 1) != -1) {
                        break;                                             
                    }
                }                                         
                
Thread.sleep(100); // delay 1/10 sec
            }

 
            System.out.println("<= " + strIn);

 
            if (strIn.length() == 0) {
                return "ERROR: len 0";
            }

 
            return strIn;
        }
        catch (Exception e) {                  
            System.out.println("send e recv Exception " + e);
            return "ERROR: send e recv Exception";
        }
    }

 
    public String sendSms (String numToSend, String whatToSend) {
        ComputeSmsData sms = new ComputeSmsData();
        sms.setAsciiTxt(whatToSend);
        sms.setTelNum(numToSend);
        sms.setSMSCTelNum("+919891030099");  // SC fixed
        String s = new String();
        s = sendAndRecv("AT+CMGS=" + (sms.getCompletePduData().length() / 2) + "\r", 30);
//        System.out.println("==> AT+CMGS=" + (sms.getCompletePduData().length() / 2));
//        System.out.println("<== " + s);
        if (s.indexOf(">") != -1) {
//            s = sendAndRecv(sms.getSMSCPduData() + sms.getCompletePduData() + "\u001A"); // usefull one day?
//            System.out.println("Inviero questo >>>> " + sms.getCompletePduData()); 

 
// if this sintax won't work try remove 00 prefix
            s = sendAndRecv("00" + sms.getCompletePduData() + "\u001A", 150);

 
//            System.out.println("<== " + s);
            return s;
        }              
        else {
            return "ERROR";
        }
    }
                         
    // used to reset message data
    private void resetGsmObj() {
        lastIndexRead = null;
        senderNum = null;
        smsMsg = null;
    }

 

 
    public String checkSms (){
        String str = new String();
        String strGsm = new String();                          
        strGsm = sendAndRecv("AT+CMGL=0", 30);  // list unread msg and sign them as read
        // if answer contain ERROR then ERROR
        if (strGsm.indexOf("ERROR") != -1) {
            resetGsmObj();
            return strGsm; // error
        }
        
        strGsm = sendAndRecv("AT+CMGL=1", 30);  // list read msg
        // if answer contain ERROR then ERROR
        if (strGsm.indexOf("ERROR") != -1) {
            resetGsmObj();
            return strGsm; // error
        }

 
        // evaluate message index
        if (strGsm.indexOf(':') <= 0) {
            resetGsmObj();
            return ("ERROR unexpected answer");
        }

 
        str = strGsm.substring(strGsm.indexOf(':') + 1,strGsm.indexOf(','));
        str = str.trim(); // remove white spaces
//        System.out.println("Index: " + str);
        lastIndexRead = str;
                                                 
        // find message string
        // -------------------
        // look for start point (search \r, then skip \n, add and one more for right char
        int startPoint = strGsm.indexOf("\r",(strGsm.indexOf(":") + 1)) + 2;
        int endPoint = strGsm.indexOf("\r",startPoint + 1);
        if (endPoint == -1) {
            // only one message
            endPoint = strGsm.length();
        }

 
        // extract string
        str = strGsm.substring(startPoint, endPoint);
        System.out.println("String to be decoded :" + str);

 
        ComputeSmsData sms = new ComputeSmsData();
        sms.setRcvdPdu(str);
      //  SMSCNum = new String(sms.getRcvdPduSMSC());
        senderNum = new String(sms.getRcvdSenderNumber());
        smsMsg = new String(sms.getRcvdPduTxt());

 
        System.out.println("SMSC number:   " + sms.getRcvdPduSMSC());
        System.out.println("Sender number: " + sms.getRcvdSenderNumber());
        System.out.println("Message: " + sms.getRcvdPduTxt());
        
        String  RcvdPduSMSC = sms.getRcvdPduSMSC();
        String  RcvdSenderNumber = sms.getRcvdSenderNumber();
        String  RecivedMessage = sms.getRcvdPduTxt();
        String  ReadMessage = readSms();
        System.out.println("Agni"+RcvdPduSMSC);
        System.out.println("Agni"+RcvdSenderNumber);
        System.out.println("Agni"+RecivedMessage);
        System.out.println("Agni"+ReadMessage);
       // InsertDB insertdb = new InsertDB("");
    
        return "OK";
    }

 
    public String readSmsSender() {
        return senderNum;
    }
    
    public String readSms() {
        return smsMsg;
    }
    
    public String delSms() {   
        if (lastIndexRead != "") {                
            return sendAndRecv("AT+CMGD=" + lastIndexRead, 30);
        }
        return ("ERROR");
    }
}

 
---------------------------- Enjoy The code  -----------------------------  


No comments:

Post a Comment