11

I have successfully Implemented Java Api and Started to Send SMS and Dial Calls.But I am finding it impossible to answer the incoming call .I have tried the RI event ( serialPort.notifyOnRingIndicator(true);).But it is not firing only DATA_AVAILABLE event is Firing

  1. I have tried reading input buffer and On detecting "RING" send ATA Command But its not working not able to detect RING even though when written dircetly to Console from InputStream it Contains RING
  2. Tried to send ATA Command when FROM Case RI(Ring Indicator) in serial event handler .

I am trying to implement An IVR System .How to send ATA command in this scenario , How to detect the RING and Why Is the RI event Not firing

Code

package sample;



    import java.io.*;
    import java.util.*;

    import gnu.io.*;

    import java.io.*;

    import javax.sound.sampled.AudioInputStream;
    import javax.sound.sampled.AudioSystem;
    import javax.sound.sampled.Clip;
    import javax.sound.sampled.LineUnavailableException;
    import javax.sound.sampled.UnsupportedAudioFileException;

    import org.apache.log4j.chainsaw.Main;

    import sun.audio.*;

    public class GSMConnect implements SerialPortEventListener, 
     CommPortOwnershipListener {

     private static String comPort = "COM6"; // This COM Port must be connect with GSM Modem or your mobile phone
     private String messageString = "";
     private CommPortIdentifier portId = null;
     private Enumeration portList;
     private InputStream inputStream = null;
     private OutputStream outputStream = null;
     private SerialPort serialPort;
     String readBufferTrial = "";
     /** Creates a new instance of GSMConnect */
     public GSMConnect(String comm) {

       this.comPort = comm;

     }

     public boolean init() {
       portList = CommPortIdentifier.getPortIdentifiers();
       while (portList.hasMoreElements()) {
         portId = (CommPortIdentifier) portList.nextElement();
         if (portId.getPortType() == CommPortIdentifier.PORT_SERIAL) {
           if (portId.getName().equals(comPort)) {
               System.out.println("Got PortName");
             return true;
           }
         }
       }
       return false;
     }

     public void checkStatus() {
       send("AT+CREG?\r\n");
     }

     public void dial(String phoneNumber) {
       try {
    //dial to this phone number

         messageString = "ATD" + phoneNumber + ";\r\n";
         outputStream.write(messageString.getBytes());
         System.out.println("Called ");
       } catch (IOException e) {
         e.printStackTrace();
       }
     }

     public void send(String cmd) {
       try {
         outputStream.write(cmd.getBytes());
       } catch (IOException e) {
         e.printStackTrace();
       }
     }

     public void sendMessage(String phoneNumber, String message) {
           char quotes ='"';
       send("AT+CMGS="+quotes + phoneNumber +quotes+ "\r\n");
       try {
        Thread.sleep(2000);
    } catch (InterruptedException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
        //   send("AT+CMGS=\""+ phoneNumber +"\"\r\n");
       send(message + '\032');
       System.out.println("Message Sent");
     }

     public void hangup() {
       send("ATH\r\n");
     }
     public void welcomeMessage(){

         // open the sound file as a Java input stream
            String gongFile = "C:\\Users\\SACHIN\\Desktop\\7001110.mp3";
            InputStream in;
            try {
                in = new FileInputStream(gongFile);
                 // create an audiostream from the inputstream
               // AudioStream audioStream = new AudioStream(in);
                // play the audio clip with the audioplayer class
               // AudioPlayer.player.start(audioStream);
                Clip clip = AudioSystem.getClip();
                AudioInputStream inputStream = AudioSystem.getAudioInputStream(
                  Main.class.getResourceAsStream(gongFile));
                clip.open(inputStream);
                clip.start(); 
            } catch (IOException | UnsupportedAudioFileException | LineUnavailableException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }





     }
     public void connect() throws NullPointerException {
       if (portId != null) {
         try {
           portId.addPortOwnershipListener(this);

           serialPort = (SerialPort) portId.open("MobileGateWay", 2000);
           serialPort.setSerialPortParams(115200,SerialPort.DATABITS_8,SerialPort.STOPBITS_1,SerialPort.PARITY_NONE);
         } catch (PortInUseException | UnsupportedCommOperationException e) {
           e.printStackTrace();
         }

         try {
           inputStream = serialPort.getInputStream();
           outputStream = serialPort.getOutputStream();

         } catch (IOException e) {
           e.printStackTrace();
         }

         try {
           /** These are the events we want to know about*/
           serialPort.addEventListener(this);
           serialPort.notifyOnDataAvailable(true);
           serialPort.notifyOnRingIndicator(true);
         } catch (TooManyListenersException e) {
           e.printStackTrace();
         }

    //Register to home network of sim card

         send("ATZ\r\n");

       } else {
         throw new NullPointerException("COM Port not found!!");
       }
     }

     public void serialEvent(SerialPortEvent serialPortEvent) {
       switch (serialPortEvent.getEventType()) {
         case SerialPortEvent.BI:
         case SerialPortEvent.OE:
         case SerialPortEvent.FE:
         case SerialPortEvent.PE:
         case SerialPortEvent.CD:
         case SerialPortEvent.CTS:
         case SerialPortEvent.DSR:
         case SerialPortEvent.RI:
             System.out.println("Ringing");

        /*try {
            Thread.sleep(5000);
            send("ATA");
        } catch (InterruptedException e1) {
            // TODO Auto-generated catch block
            e1.printStackTrace();
        }*/
        break;
         case SerialPortEvent.OUTPUT_BUFFER_EMPTY:
         case SerialPortEvent.DATA_AVAILABLE:

           byte[] readBuffer = new byte[2048];
           try {
             while (inputStream.available() > 0) 
             {
               int numBytes = inputStream.read(readBuffer);

               System.out.print(numBytes);
               if((readBuffer.toString()).contains("RING")){
               System.out.println("Enter Inside if RING Loop");    


               welcomeMessage();
               }
             }
             //readBufferTrial=readBufferTria;//+new String(readBuffer)+new Date();
             //print response message
             System.out.print(new String(readBuffer));
           } catch (IOException e) {
           }
           break;
       }
     }
     public void outCommand(){
         System.out.print(readBufferTrial);
     }
     public void ownershipChange(int type) {
       switch (type) {
         case CommPortOwnershipListener.PORT_UNOWNED:
           System.out.println(portId.getName() + ": PORT_UNOWNED");
           break;
         case CommPortOwnershipListener.PORT_OWNED:
           System.out.println(portId.getName() + ": PORT_OWNED");
           break;
         case CommPortOwnershipListener.PORT_OWNERSHIP_REQUESTED:
           System.out.println(portId.getName() + ": PORT_INUSED");
           break;
       }

     }
     public void closePort(){

        serialPort.close(); 
     }

     public static void main(String args[]) {
       GSMConnect gsm = new GSMConnect(comPort);
       if (gsm.init()) {
         try {
             System.out.println("Initialization Success");
           gsm.connect();
           Thread.sleep(5000);
           gsm.checkStatus();
           Thread.sleep(5000);
           System.out.println("Before Auto Answer");
           gsm.send("ATS0=1");
           Thread.sleep(7500);
           System.out.println("After Auto Answer set");

        //   gsm.sendMessage("87SSSXXX9105", "Trial Success ");
           Thread.sleep(5000);
         //   gsm.sendMessage("+919633XXXXX", "Third Msg");
         //  Thread.sleep(1000);
         //  gsm.dial("87SSSXXX9105");
         //  gsm.dial("87SSSXXX9105");
         //  Thread.sleep(1000);
         //  gsm.welcomeMessage();
        //   Thread.sleep(1000);
         //  gsm.welcomeMessage();// for turning on Echo ATE1&W

           Thread.sleep(20000);

           gsm.hangup();
           Thread.sleep(1000);
           gsm.closePort();
           gsm.outCommand();
           System.exit(1);


         } catch (Exception e) {
           e.printStackTrace();
         }
       } else {
         System.out.println("Can't init this card");
       }
     }


    }

Edit:-

I have found way of auto answering the call by setting auto answer mode using AT commands after modem is initialized but it is not always reliable and for the purpose I am using the modem I need to get the timing right for playing audio clip the moment when Call is answered Audio Must be played .Auto answer using AT commands answers the call but the problem of playing audio remains.So I need some way of find how to detect Ring

codefreaK
  • 3,584
  • 5
  • 34
  • 65
  • 1
    looks like this may help you https://www.daniweb.com/software-development/java/threads/14224/connecting-modem-via-java – mussdroid Jul 31 '15 at 06:02
  • @mussdroid yep this is same as that I am trying but the issue here is my code in RI case is not firing and also even though my inputstream contains RING RING when printed into console but if the same string is compared to "RING" its not finding it hence resulting in a situation equivalent to RI Case not firing any way thanx for trying to help .This was the first response That I got even after setting a bounty] – codefreaK Jul 31 '15 at 06:07
  • The main isssue needed here is explanation of RI event not triggering coz I need to understand that before going into details of the application – codefreaK Jul 31 '15 at 13:35

2 Answers2

1

I can't talk to the specific API or why you are not getting an event. However, your backup plan of parsing the inputStream looking for RING has a few potential issues.

The principal one is that your implementation is depending on RING being sent/read in the same read operation. There's no guarantee of that - it is quite possible, depending on implementation of the underlying API, that you end up with the stream one byte at a time (in which case you will get R I N G as separate strings).

My recommendation is to create a StringBuffer, append the StringBuffer as long as you have input, then check the StringBuffer.

Something like :

 case SerialPortEvent.DATA_AVAILABLE:

   StringBuffer sb = new StringBuffer();
   byte[] readBuffer = new byte[2048];
   try {
     while (inputStream.available() > 0) 
     {
       int numBytes = inputStream.read(readBuffer);
       sb.append(new String(readBuffer,0,numBytes));
       System.out.print(numBytes);
     }
     if((sb.toString()).contains("RING")){
        System.out.println("Enter Inside if RING Loop");    
        welcomeMessage();
     }
     //print response message
     System.out.print(sb.toString());
   } catch (IOException e) {
   }
   break;
crovers
  • 339
  • 4
  • 12
0

please have a look at your switch case , you don't have break; That might be issue.

case SerialPortEvent.RI:
            if( serialPortEvent.getNewValue() ) 
            {
                System.out.println("Ring Indicator On");
            }
            else 
            {
                System.out.println("Ring Indicator Off");
            }
            break;
mussdroid
  • 732
  • 1
  • 9
  • 22
  • Yes will look into it and then respond But the problem is I tried with only RI case and Commenting DataAVailable event or making it empty But still its not firing.So Most Probably it wont work.Event set only serialPort.notifyOnDataAvailable(false); – codefreaK Jul 31 '15 at 06:14
  • Dint have break in the code I pasted here that disappeared becuase there was other code in it and I accidently removed it while formatting to be put in this pag – codefreaK Jul 31 '15 at 06:22
  • in your current code here you are only breaking at the end case SerialPortEvent.DATA_AVAILABLE: , so do you have break after serialPortEven.RI case ? you need to still put in if else to see if it is on or off. – mussdroid Jul 31 '15 at 06:24
  • So lemme ask u one thing even if other events are not set true and if RI event is the only event set true and even with break the Println should be working na ?.But it aint working .THats whay forced me to post this question.Yes there was break in the code before posting it here during Editing I actually missded out – codefreaK Jul 31 '15 at 06:26
  • yeah true , it executes from entry point , you may need to check if the program enters switch case statement. – mussdroid Jul 31 '15 at 06:39
  • THats what my whole question is about it is NOt entering RI Event Case even when the inputstream Contains RING RING ie the call in ringing the RI event was not firing – codefreaK Jul 31 '15 at 06:42
  • i see , no events being triggered may due to the program exiting and ending before it had the chance to do na, do you have thread somewhere exits before entering the event like main thread , you may need to add loop but sleep thread inside ? – mussdroid Jul 31 '15 at 06:49
  • No I tried it without System.exit(1); Coz othere wise it would not end and so In order to exit the program it was added – codefreaK Jul 31 '15 at 07:13