Gemalto is now part of the Thales Group, find out more.

You are here

Problem handling ATCommand class during CSD data call reception | Thales IoT Developer Community

November 1, 2016 - 12:03am, 3694 views

Hello,

I try to realize GSM-RS232 tunnel between two BGS5 modules using data call CSD. I am facing problem with behaviour of java ATCommand class in this case. Java code is mainly intented to accept call, read data in trasparent data ****, response some commands and resend rest to serial line. I am able to realize connection, but reconnection attemps are problematic. I get often exception "java.io.IOException: ATCommand class instance is not in transparent data ****" when connection is closed on other side and sometimes programme freeze and ****m is reset by watchdog. I need to say that external realization of the task using AT commands on serial terminal is much more robust than realization in java code. Here is part of Main class code:

public class Main extends MIDlet {
  private static boolean bRunning = true;
  private ATCommand atc;
  private String Response;
  private long t0, t1, t, tsec;
  private boolean bCall = false;
  private boolean bCallAccepted = false;
  private long tCall = 0;
  private static final int PERIOD = 3000;  //ms (3s)
  private InputStream callin = null;
  private OutputStream callout = null;
  private static int ***_DATA_SIZE = 256;
  private byte[] calldata = new byte[***_DATA_SIZE];
  private static final String CONNECTION_STRING = "comm:COM0;baudrate=9600;autocts=on;autorts=on"; // AC0, 9600!
  private CommConnection serialconn = null;
  private InputStream serialin = null;
  private OutputStream serialout = null;
  private static final String CMD_OUT0 = "$$OUT=0\r";
  private static final String CMD_OUT1 = "$$OUT=1\r";
  private static final String CMD_OK = "$$OK\r";
  private static final long CALL_TIMEOUT = 35000;  //35s
  private String str;   //temporary string
  private static Watchdog2 wd;

  public Main() {
    System.out.println("Constructor");
    wd = new Watchdog2();
  }

  protected void startApp() throws MIDletStateChangeException {
       
    instance = this;
   
    wd.start(60); //60s
    System.out.println("WD started");

    try {
      // create an instance of ATCommand (support CSD connection!!!)
      atc = new ATCommand(true);

      // configure
      //echo on
      Response = atc.send("ATE1\r");
      System.out.println(Response);
      //set GPIO23 to output
      Response = atc.send("AT^SCPIN=1,22,1\r");
      System.out.println(Response);
      //set pin on
      Response = atc.send("AT^SSIO=22,1\r");
      System.out.println(Response);
      //set GPIO8 to input
      Response = atc.send("AT^SCPIN=1,7,0\r");
      System.out.println(Response);
      //get GPIO8 input
      Response = atc.send("AT^SGIO=7\r");
      System.out.println(Response);
      bInputState = Response.indexOf(": 1") > 0 ? true : false;
     
      //set incoming call indicator
      //Response = atc.send("AT+CRC=1\r");  //"+CRING: REL ASYNC"
      Response = atc.send("AT+CRC=0\r");
      System.out.println(Response);

      // create the AT command listener
      ATCommandListener listener = new ATCommandListener() {
     
        public void RINGChanged(boolean SignalState) {
          System.out.println("ring: " + SignalState);
        }

        public void DSRChanged(boolean SignalState) {
          System.out.println("dsr: " + SignalState);
        }

        public void DCDChanged(boolean SignalState) {
          System.out.println("dcd: " + SignalState);
        }

        public void CONNChanged(boolean SignalState) {
          System.out.println("conn: " + SignalState);
          if (!SignalState) {
            System.out.println("End of connection "+ System.currentTimeMillis());
            bCall = false;
          }
        }

        public void ATEvent(final String Event) {
          System.out.println("received URC: " + Event);
          // search for call related URCs
          //if (Event.indexOf("CRING: REL ASYNC") >= 0) {
          if (Event.indexOf("RING") >= 0) {
            if (bRunning) {
              if (!bCall && !bCallAccepted) {   //!!!
                System.out.println("Call ring " + System.currentTimeMillis());
                bCall = true;
              }
            }
          }
        }
      };

      // add (activate) the listener
      atc.addListener(listener);
     
      //start time
      t0 = System.currentTimeMillis();
      t1 = t0;
      t = t0;

      //loop
      while (bRunning) {
        //get time
        t = System.currentTimeMillis();
               
        //periodic action
        if ((t-t1) >= PERIOD) {  //~3s
          t1 = t;
          //kick watchdog
          wd.kick();
                   
          //read input
          if (!bCall && !bCallAccepted) {
            Response = atc.send("AT^SGIO=7\r");
            bInputState = Response.indexOf(": 1") > 0 ? true : false;
          }
        }
       
        //--- test for call
        if (bCall) {
          //not accepted yet
          if (!bCallAccepted) {
            //accept the call
            System.out.println("Accept call " + t);
            if (CallConnect()) {
              callin = atc.getDataInputStream();
              callout = atc.getDataOutputStream();
              bCallAccepted = true;
              Thread.sleep(100);  //wait?
              tCall = t;
            }
            else {
              bCall = false;
            }
          }
          //accepted -> resent data
          if (bCallAccepted) {
            //test for data carrier
            if (!atc.getCONN()) {
              System.out.println("Lost connection " + t);
              bCall = false;
            }
            //test for data ****
            else if (atc.getDCD()) {
              //test for data timeout?
              try {
                int avail, a;
                //read from call input (write to serial output)
                avail = callin.available();
                if (avail > 0) {
                  if (avail > ***_DATA_SIZE) {
                    avail = ***_DATA_SIZE;
                  }
                  a = callin.read(calldata, 0, avail);
                  if (a > 0) {
                    //reset call time
                    tCall = t;
                    //test for special commands
                    if (Utils.ByteArrayCompare(calldata, 0, a, CMD_OUT0)) {
                      System.out.println("Cmd: out0");
                      SwitchOutput(0);
                      callout.write(CMD_OK.getBytes());
                    }
                    else if (Utils.ByteArrayCompare(calldata, 0, a, CMD_OUT1)) {
                      System.out.println("Cmd: out1");
                      SwitchOutput(1);
                      callout.write(CMD_OK.getBytes());
                    }
                    else {
                      //write to serial output
                      serialout.write(calldata, 0, a);
                      System.out.println("RD (" + a + ")");
                    }
                  }
                }
             
                //read from serial input (write to call output)
                avail = serialin.available();
                if (avail > 0) {
                  if (avail > ***_DATA_SIZE) {
                    avail = ***_DATA_SIZE;
                  }
                  a = serialin.read(calldata, 0, avail);
                  if (a > 0) {
                    //reset call time
                    tCall = t;
                    //write to serial output
                    callout.write(calldata, 0, a);
                    System.out.println("WD (" + a + ")");
                  }
                }
              } catch (Exception ex) {
                ex.printStackTrace();
              }
            }
           
            //test for call timeout
            if ((t-tCall) > CALL_TIMEOUT) {
              bCall = false;
              System.out.println("Call timeout");
            }
           
          }
        }
        //call finished, but was accepted before
        else if (bCallAccepted) {
          //hang call down
          System.out.println("Hang call down " + t);
          CallDisconnect();
          callin = null;
          callout = null;
          bCallAccepted = false;
        }
       
      }
     
      } catch (Exception e) {
      e.printStackTrace();
    }
       
    //quit
    destroyApp(true);
  }

  protected void pauseApp() {
  }
   
  protected void destroyApp(boolean arg0) throws MIDletStateChangeException {
    System.out.println("Stopping");
    System.out.println("Elapsed time " + (System.currentTimeMillis()-t0)/1000 + "s");
      
    //no loop
    bRunning = false;

    //disconnect all calls
    if (bCallAccepted) {
      try {
        CallDisconnect();
        callin = null;
        callout = null;
        bCallAccepted = false;
      } catch (Exception e) {
        e.printStackTrace();
      }
    }
   
    //wait a bit
    try {
      Thread.sleep(2000);
    } catch (Exception ignored) {
    }
       
    //release atc
    try {
      atc.release();
    } catch (Exception e) {
      e.printStackTrace();
    }
       
       
    System.out.println("Finished");
    notifyDestroyed();
  }

  //----------------------------------
 
  /**
  * getInstance()
  */
  public static Main getInstance() {
    return instance;
  }
   
  /**
  * stop()
  */
  public static void stop() {
    System.out.println("Stop (wd)");
    bRunning = false;
    wd.start(0);
  }
 
  //--------------
 
  boolean CallConnect() throws Exception {
    try {
      //open ASC
      System.out.println("Serial - opening: " + CONNECTION_STRING);
      serialconn = (CommConnection) Connector.open(CONNECTION_STRING, Connector.READ_WRITE, true);
      serialin = serialconn.openInputStream();
      serialout = serialconn.openDataOutputStream();
  
      //accept call
      System.out.println("Send ATA");
      Response = atc.send("ATA\r");
      System.out.println(Response);
      if (Response.indexOf("CONNECT") > -1) {
        System.out.println("Call connected");
        return true;
      }
      else {
        System.out.println("Call not connected");
        CallDisconnect(); //close port
        return false;
      }
    }
    catch (Exception e) {
      e.printStackTrace();
      return false;
    }
  }
 
  boolean CallDisconnect() throws Exception {

    //test for connection
    boolean bret = true;
   
    try {
      //is data ****
      if (atc.getDCD()) {
        System.out.println("Call break");
        //enter command ****
        Response = atc.breakConnection();
        System.out.println(Response);
        Thread.sleep(1500);
      }
    } catch (Exception e) {
      e.printStackTrace();
    }
   
    try {
      if (atc.getCONN()) {
        //disconnect all calls
        System.out.println("Disconnect all calls");
        Response = atc.send("ATH\r");
        System.out.println(Response);
        if (Response.indexOf("OK") >= 0) {
          System.out.println("Calls disconnected");
          bret = true;
        }
        else {
          bret = false;
        }
      }
    } catch (Exception e) {
      e.printStackTrace();
    }
     
    try {
      System.out.println("Serial - close connection");
      if (serialout != null) {
        serialout.close();
        serialout = null;
      }
   
      System.out.println("Serial - close in");
      if (serialin != null) {
        serialin.close();
        serialin = null;
      }
   
      System.out.println("Serial - close conn");
      if (serialconn != null) {
        serialconn.close();
        serialconn = null;
      }
    } catch (Exception e) {
      e.printStackTrace();
    }

    try {
      //reset incoming call indicator!!!
      //Response = atc.send("AT+CRC=1\r");  //"+CRING: REL ASYNC"!!!
      Response = atc.send("AT+CRC=0\r");
      System.out.println(Response);
      //again
      Response = atc.send("AT+CRC=0\r");
      System.out.println(Response);
   
    } catch (Exception e) {
      e.printStackTrace();
    }

    //
    if (bret)
      System.out.println("Call disconnected");
    else
      System.out.println("Call not disconnected");
   
    return bret;
  }
}

/////////// Here is system log //////////////

/// 1st Attemp ///
ring: true
received URC:
RING

Call ring 1072928918996
Accept call 1072928918945
Serial - opening: comm:COM0;baudrate=9600;autocts=on;autorts=on
ring: false
Send ATA
ring: true
received URC:
RING

ring: false
conn: true
ATA
CONNECT

Call connected
dcd: true
Cmd: out0
RD (3)
Cmd: out1
RD (3)
dcd: false
conn: false
End of connection 1072928961981
java.io.IOException: ATCommand class instance is not in transparent data ****
 - com.cinterion.io.ATCommand$InputStreamDataConnection.available(ATCommand.java:563)
 - CallReceiver.Main.startApp(Main.java:95)
 - javax.microedition.midlet.MIDletTunnelImpl.callStartApp(), bci=1
 - com.sun.midp.midlet.MIDletPeer.startApp(), bci=5
 - com.sun.midp.midlet.MIDletStateHandler.startSuite(), bci=261
 - com.sun.midp.main.AbstractMIDletSuiteLoader.startSuite(), bci=38
 - com.sun.midp.main.CldcMIDletSuiteLoader.startSuite(), bci=5
 - com.sun.midp.main.AbstractMIDletSuiteLoader.runMIDletSuite(), bci=134
 - com.sun.midp.main.AppIsolateMIDletSuiteLoader.main(), bci=26
Hang call down 1072928962129
Serial - close connection
Serial - close in
Serial - close conn
AT+CRC=0
OK

AT+CRC=0
OK

Call disconnected

/// 2nd Attemp ///
ring: true
ring: false
ring: true
received URC:
RING

Call ring 1072929106921
Accept call 1072929106963
Serial - opening: comm:COM0;baudrate=9600;autocts=on;autorts=on
received URC:
RING

ring: false
Send ATA
conn: true
ATA
CONNECT

dcd: true
Call connected
Cmd: out0
RD (3)
Cmd: out1
RD (3)
dcd: false
conn: false
End of connection 1072929148462
Hang call down 1072929148513
Serial - close connection
Serial - close in
Serial - close conn
AT+CRC=0
OK

AT+CRC=0
OK

Call disconnected

/// 3rdt Attemp ///
ring: true
ring: false
ring: true
ring: false
ring: true
ring: false
ring: true
ring: false
ring: true
ring: false
received URC:
RING

Call ring 1072929212957
ring: true
ring: false
ring: true
ring: false
ring: true
ring: false
ring: true
ring: false
ring: true
ring: false
ring: true
ring: false

/// RESTART (by WD) ///

I am not sure how to handle exception of callin.available() function, which wasn't used in transparent data ****. Other side can close data **** (+++) and connection at any moment and I am not sure how to avoid the exception and how to handle it. I see that behaviour of ATCommand class is not good in my case. It is enough expensive to realize many connections for testing. I would be glad for any helpful example, how to handle data **** better to behave the same way as externally through serial.

Here are my versions of: JRC-1.50.3.jad, cwmblib_1.0.jar

Thanks.

nelup