SMS App (Extension from Web-based CRM Module-Telephony)

All Case Experiences in Topic format. Easy reading mode for contextual understanding. Quickie snapshot and howtos Files are linked into http://compiere.red1.org/

Postby zam » Tue Sep 26, 2006 11:19 am

Useful AT Command Guide
http://www.cellular.co.za/hayesat.htm#SMS%20Command%20Set
Syntax Rules
* A command string should start with "AT" or "at", except for the commands "A/" and "+++". At or aT are invalid.
* Several commands can be given in one command string.
* The commands can be given in upper or lower case.
* A command string should contain less than 40 characters.
* When an error is made during the typing of the command, it can be corrected using the backspace key.
* Commands and command strings must be terminated with an <ENTER>, except +++ and A/
* A telephone number can exist of following characters: 1 2 3 4 5 6 7 8 9 * = , ; # + > . All other characters are ignored (space, underscore ). They help formatting the dialstring.
* Commands that use a numerical parameter, can be used without a numerical value. In this case the command will be issued with the value zero.
* If the command string contains two consecutive commands without parameter, as discussed above, the modem will respond with an error.
* After the command ATZ has been issued, a pause of two seconds should be respected before entering the next commands.
Last edited by zam on Tue Sep 26, 2006 12:44 pm, edited 1 time in total.
zam
 
Posts: 49
Joined: Mon Jul 17, 2006 9:30 am

Postby zam » Tue Sep 26, 2006 12:15 pm

http://www.cellular.co.za/hayesat.htm#SMS%20Command%20Set
AT+CMGF: Message Format:

Command Possible response(s)
+CMGF=[<mode>]
+CMGF?
+CMGF: <mode>
+CMGF=?
+CMGF: (list of supported <mode>s)

<mode>: 0: PDU mode;1: text mode;

In our case, we initialize message format as 1
AT+CSCA: Service Center Address:

Command Possible response(s)
+CSCA=<sca>[,<tosca>]
+CSCA?
+CSCA: <sca>,<tosca>
+CSCA=?

<sca> = service center address;

SCA should contain the country code number. Sending an SMS will not work when the SCA number is not entered
AT+CMGL: List Messages:

Command Possible response(s)
+CMGL[=<stat>]
+CMGL: message...
+CMGL=?
+CMGL: (list of supported <stat>s)

<stat>: status of messages to be read.

defined values:
0: received unread
1: received read;
2: stored unsent;
3: stored sent;
4: all;

can also represent the number with these: (eg:AT+CMGL="ALL")
"REC UNREAD": received unread
"REC READ" : received read;
"STO UNSENT": stored unsent;
"STO SENT" : stored sent;
"ALL" : all;
AT+CMGR: Read Message:

Command Possible response(s)
+CMGR=<index>
+CMGR: message... +CMGR=?


AT+CMGS: Send Message:

Command Possible response(s)
+CMGS=<da>[,<toda>]
+CMGS: <mr> +CMGS=?

<da> = Destination Address;


AT+CMGD: Delete Message:

Command Possible response(s)
+CMGD=<index>
+CMGD=?

Important ERROR messages:
CMS Errors:

300: ME Failure;
302: Operation not allowed;
303: Operation not supported;
304: Invalid PDU mode parameter;
305: Invalid text mode parameter;
320: memory failure;
321: invalid memory index;
322: memory full;
330: SCA unknown;
500: Unknown error



I think this is useful but yet to be tested
AT+CNMI: New Message indication to TE


Command Possible response(s) +CNMI=[<mode>[,<mt>[,<bm>[,<ds>[,<bfr>]]]]]
+CNMI?
+CNMI: <mode>,<mt>,<bm>,<ds>,<bfr>
+CNMI=?+CSCB: (list of supported <mode>s,<mt>s,<bm>s,<ds>s,<bfr>s)


<mode>: 0: buffer in TA;

1: discard indication and reject new SMs when TE-TA link is reserved; otherwise forward directly;

2: buffer new Sms when TE-TA link is reserved and flush them to TE after reservation; otherwise forward directly to the TE;

3: forward directly to TE;<mt>: 0: no SMS-DELIVER are routed to TE;

1: +CMTI: <mem>,<index> routed to TE;

2: for all SMS_DELIVERs except class 2: +CMT: .... routed to TE; class 2 is indicated as in <mt>=1;

3: Class 3: as in <mt>=2;

other classes: As in <mt>=1;

<bm>: same as <mt>, but for CBMs;
<ds>: 0: No SMS-STATUS-REPORT are routed to TE;

1: SMS-STATUS-REPORTs are routed to TE, using +CDS: ...

<bfr>: 0: TA buffer is flushed to TE (if <mode>=1..3);

1: TA buffer is cleared (if <mode>=1..3);

---> Only when <mt> is different from 0, you will get a message that a new SMS has been received.
zam
 
Posts: 49
Joined: Mon Jul 17, 2006 9:30 am

Postby zam » Tue Sep 26, 2006 1:38 pm

zam
 
Posts: 49
Joined: Mon Jul 17, 2006 9:30 am

Postby sbahrin » Tue Sep 26, 2006 4:18 pm

The SimpleRead class implements the SerialPortEventListener, meaning that this class has a role as a Listener. To be this role, it must have some method defined in the SerialPortEventListener.


The object that do the listening is the serialPort object, where it is listening to a certain event, and in this case the SerialPortEvent. When there is an event, it will delegate the event to the listener class, in this case SimpleRead, and execute the serialEvent() method.

In this sample program, the time given for the each serialPort object to wait for an event is 20 seconds, as given by the codes in the run() method.

Code: Select all
    public void run() {
        try {
            Thread.sleep(20000);
        } catch (InterruptedException e) {}
    }


After this 20 seconds, the thread will end.

Therefore, if you want to make it endlessly waiting for an event, replace it with a while loop.

Code: Select all
    public void run() {
        while ( readThread != null ) {
          try {
             Thread.sleep(10000);
          } catch (InterruptedException e) {}
        }
    }



And, normally I like to create a stop() method, but it depends on your own style.

Code: Select all
    public void stop() {
        readThread = null;
    }
Last edited by sbahrin on Tue Sep 26, 2006 4:23 pm, edited 2 times in total.
sbahrin
Regular
 
Posts: 81
Joined: Fri Dec 17, 2004 6:47 pm
Location: Malaysia

Postby sbahrin » Tue Sep 26, 2006 4:18 pm

Pls. take note that... you still need a Thread.sleep() method in the while loop.

The purpose of sleep() method is to give other thread a chance to run.
sbahrin
Regular
 
Posts: 81
Joined: Fri Dec 17, 2004 6:47 pm
Location: Malaysia

Postby zam » Tue Sep 26, 2006 5:01 pm

I've tested on receiving incoming SMS. The command to be set is +CNMI. I did not set the setting before thus the hyperterminal did not inform if there is an incoming SMS.
at+cmgf=1
OK

at+cnmi=?
+CNMI: (0-2),(0-3),(0,2,3),(0-2),(0,1)

OK

at+cnmi=1,2,0,0,0
OK

+CMT: "+60193384826",,"06/09/26,16:11:29+32"
test


if i set send AT+CNMI=1,2,0,0,0 , the result would be
+CMT: "+60193384826",,"06/09/26,16:11:29+32"
test

sender ->"+60193384826"
message-> test

If I set send AT+CNMI=1,1,0,0,0, the result would be
+CMTI: "MT",1

saying that a msg has been put inside memory of index 1

http://www.control.com.sg/at_commands_sms.aspx#Sending%20SMS%20using%20using%20AT%20commands

6/10/2006-Do List : Test the output display if +CNMI is set to 2,2,0,0,0
+CNMI=2,2,2,1,1 +CNMI=2,1,1,0,0
Last edited by zam on Fri Oct 06, 2006 10:53 am, edited 3 times in total.
zam
 
Posts: 49
Joined: Mon Jul 17, 2006 9:30 am

Postby sureshquest » Tue Sep 26, 2006 5:17 pm

sureshquest wrote:In java the timer is simple, just create a thread and loop tht forever and put a sleep inside periodically.
sureshquest
Regular
 
Posts: 69
Joined: Wed Sep 15, 2004 11:09 pm
Location: India

Postby sbahrin » Wed Sep 27, 2006 7:38 am

Sorry because this is out of topic buat I have to reply to Mr. Suresh.

In java, there is specific class for this purpose, the Timer class. The class that want to use this must extends the TimerTask class which is an abstract class and the class that extends it must override the run() method.

The purpose of Timer is, doing something at some later time, or/and doing something periodically.

The Thread is exclusively for the purpose of put a thread into a sleep state so that other thread will have a chance to run.

Anyway, you can still manipulate the thread, and create your own timer with it (without using the Timer and TimerTask class).

But, it is a good idea, to use something for the right purpose of using it.
sbahrin
Regular
 
Posts: 81
Joined: Fri Dec 17, 2004 6:47 pm
Location: Malaysia

Postby sureshquest » Wed Sep 27, 2006 11:32 am

Well, It goes like the saying, "All Roads Lead to Rome". :D

As long as it serves the purpose it is fine.

Cheers Guys. 8)
sureshquest
Regular
 
Posts: 69
Joined: Wed Sep 15, 2004 11:09 pm
Location: India

Postby zam » Wed Sep 27, 2006 4:30 pm

I did read all the suggestions and a bit lost here :D. I'll do some reading first on thread or timer.
zam
 
Posts: 49
Joined: Mon Jul 17, 2006 9:30 am

Postby zam » Fri Sep 29, 2006 1:15 pm

I used SimpleWrite for sending SMS. Task has been completed.

I used SimpleRead for receiving SMS.The important command to be set in order for system to instantly publish the incoming SMS is +CNMI. +CNMI must be set to 1,2,0,0,0. As a result, SMS is able to be displayed on the console.

Code: Select all
/*
* @(#)SimpleRead.java   1.12 98/06/25 SMI
*
* Copyright (c) 1998 Sun Microsystems, Inc. All Rights Reserved.
*/

import java.io.*;
import java.util.*;
import javax.comm.*;

public class SimpleRead implements Runnable, SerialPortEventListener {
    static CommPortIdentifier portId;
    static Enumeration portList;
      static SerialPort serialPort;
    static OutputStream outputStream;
   InputStream inputStream;
    Thread readThread;
   
//AT Commands to be sent ---------------------------------------
    static String destinationAddress = "0178869378";

   //Reset modem
   static String reset ="ATZ\r";
   
   //Check connection between modem and COM port
   static String atcheck = "AT\r";
   
   //Set message format to be text
   static String cmgf = "AT+CMGF=1\r";
   
   //Set how the modem will response when a SMS is received
   static String cnmi ="AT+CNMI=1,2,0,0,0\r";
   
   
//Main ()----------------------------------------------------------------------
    public static void main(String[] args) {
        portList = CommPortIdentifier.getPortIdentifiers();

        while (portList.hasMoreElements()) {
            portId = (CommPortIdentifier) portList.nextElement();
            if (portId.getPortType() == CommPortIdentifier.PORT_SERIAL) {
               if (portId.getName().equals("COM1")) {
                  
//Fixed Setup---------------------------------------------------------------
                   // System.out.println("COM1");
                  try
                   {
                        serialPort = (SerialPort)portId.open("SimpleWriteApp", 2000);
                   }
                   catch (PortInUseException e)
                   {
                        System.out.println("PortInUseException");
                   }
                   try
                   {
                        outputStream = serialPort.getOutputStream();
                   }
                   catch (IOException e){}
                   try
                   {
                         serialPort.setSerialPortParams(9600,
                         SerialPort.DATABITS_8,
                         SerialPort.STOPBITS_1,
                         SerialPort.PARITY_NONE);
                    }
                    catch (UnsupportedCommOperationException e){} 
//Initial setup of AT Command----------------------------------------------
                    try
                    {
                      outputStream.write(reset.getBytes());
                    }
                    catch(IOException e){}
                    try
                    {
                       Thread.sleep(1000);
                    }
                    catch(InterruptedException e){}
                    try
                    {
                         outputStream.write(cmgf.getBytes());
                    }
                    catch(IOException e){}
                    try
                    {
                       Thread.sleep(1000);
                    }
                    catch(InterruptedException e){}
                   try
                    {
                         outputStream.write(cnmi.getBytes());
                    }
                    catch(IOException e){};
                    try
                    {
                       Thread.sleep(1000);
                    }
                    catch(InterruptedException e){}

//Read SMS--------------------------------------------------------------------
                    SimpleRead reader = new SimpleRead();
                }
            }
        }
    }
     public SimpleRead() {
        try
        {
            serialPort = (SerialPort) portId.open("", 2000);
        }
        catch (PortInUseException e){System.out.println("Port already in used");
        }
        try
        {
            inputStream = serialPort.getInputStream();
        }
        catch (IOException e){System.out.println("InputStream");   
        }
       try
       {
            serialPort.addEventListener(this);
       }
       catch (TooManyListenersException e){System.out.println("TooManyListenersException");}
       
       serialPort.notifyOnDataAvailable(true);
        try
        {
                serialPort.setSerialPortParams(9600,
                SerialPort.DATABITS_8,
                SerialPort.STOPBITS_1,
                SerialPort.PARITY_NONE);
        }
        catch (UnsupportedCommOperationException e){System.out.println("UnsupportedCommOperationException");}
        readThread = new Thread(this);
        readThread.start();
    }

    public void run()
    {
       System.out.println("Ready to Read");
       try
       {
            Thread.sleep(20000);
        }
       catch (InterruptedException e) {}
    }

    public void serialEvent(SerialPortEvent event)
    {
        switch(event.getEventType()) {
        case SerialPortEvent.BI:
           System.err.println("Break Interrupt");
        case SerialPortEvent.OE:
           System.err.println("OE");
        case SerialPortEvent.FE:
           System.err.println("FE");
        case SerialPortEvent.PE:
           System.err.println("PE");
        case SerialPortEvent.CD:
           System.err.println("CD");
        case SerialPortEvent.CTS:
           System.err.println("Clear To Send");
        case SerialPortEvent.DSR:
           System.err.println("Data Set Ready");
        case SerialPortEvent.RI:
           System.err.println("Ring Indicator");
        case SerialPortEvent.OUTPUT_BUFFER_EMPTY:
            break;
        case SerialPortEvent.DATA_AVAILABLE:
            byte[] readBuffer = new byte[20];
            try
            {
                while (inputStream.available() > 0)
                {
                    int numBytes = inputStream.read(readBuffer);
                }
                System.out.print(new String(readBuffer)+"\n");
                //System.out.print("Reading");
            }
            catch (IOException e){System.out.println("IOException");}
            break;
        }
    }
}
Last edited by zam on Fri Oct 06, 2006 12:06 pm, edited 3 times in total.
zam
 
Posts: 49
Joined: Mon Jul 17, 2006 9:30 am

Postby zam » Fri Sep 29, 2006 3:57 pm

Incoming SMS being displayed on the console.

Image
zam
 
Posts: 49
Joined: Mon Jul 17, 2006 9:30 am

Postby red1 » Wed Oct 11, 2006 9:42 am

We have move our project discussion to SourceForge under Adempiere. http://sourceforge.net/forum/forum.php? ... _id=610548
red1
Site Admin
 
Posts: 2415
Joined: Tue Jul 06, 2004 3:01 pm
Location: Kuala Lumpur, Malaysia

Previous

Return to Compiere Case Workshop

Who is online

Users browsing this forum: No registered users and 1 guest

cron