package communication.sms; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.util.Enumeration; import java.util.StringTokenizer; import java.util.Vector; import javax.comm.CommPortIdentifier; import javax.comm.SerialPort; /** * Requires javacomm api 2.0 * Tested mobile devices: Vodafone Connect Card UMTS/GPRS * */ public class SMS { private InputStream in; private OutputStream out; private int timeout = 30; private static final int smsMaxLength = 160; public static boolean debug = false; SMS(String porta) { try { CommPortIdentifier portId = CommPortIdentifier.getPortIdentifier(porta); SerialPort sp = (SerialPort)portId.open("Sms_GSM", 0); sp.setSerialPortParams(9600, SerialPort.DATABITS_8, SerialPort.STOPBITS_1, SerialPort.PARITY_NONE); sp.setFlowControlMode(SerialPort.FLOWCONTROL_NONE); in = sp.getInputStream(); out = sp.getOutputStream(); } catch (Exception e) { e.printStackTrace(); System.exit(1); } } public void resetModem() throws SmsException, InterruptedException, IOException { String operation = "Initializing modem"; execCommand("+++AT", operation, false); // delay for 20 sec/10 execCommand("AT&F", operation, true); execCommand("ATE0", operation, true); // echo off execCommand("AT +CMEE=1", operation, true); // verbose error messages execCommand("AT+CMGF=0", operation, true); // set pdu mode // sendAndRecv("AT V1E0S0=0&D2&C1", 1000000); } private String sendAndRecv(String s, int timeout, boolean expectAnyResponse) throws SmsException, InterruptedException, IOException { // clean serial port input buffer in.skip(in.available()); if (debug) System.out.println("=> " + s); s = s + "\r"; // add CR out.write(s.getBytes()); out.flush(); String strIn = new String(); if (!expectAnyResponse) timeout = 1; 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 } /* DEBUG */ if (debug) System.out.println("<= " + strIn); if ((strIn.length() == 0) && expectAnyResponse) throw new SmsException("No response from modem, command:\r\n" + s); return strIn; } public String execCommand(String cmd, String operationDescription, boolean expectAnyResponse) throws SmsException, InterruptedException, IOException { String s = sendAndRecv(cmd, timeout, expectAnyResponse); if (s.trim().indexOf("ERROR") != -1) throw new SmsException("Command failed.\r\n" + cmd + "\r\nOperation: " + operationDescription + "\r\nResponse is " + s); return s; } public void sendSms(String SMSCnumber, String destNumber, String message) throws SmsException, IOException, InterruptedException { if (message.length() > smsMaxLength) throw new SmsException("Exceeded sms text length, max " + smsMaxLength + " actual " + message.length()); resetModem(); execCommand("AT+CSCA=\"" + SMSCnumber + "\",145", "Setting SMSC number", true); execCommand("at+csdh=1", "", true); execCommand("at+csmp=17,167,0,0", "", true); execCommand("AT+CPMS=\"SM\"", "Selecting the SMS memory section " + "of the SIM card", true); execCommand("at+cmgf=1", "Setting text mode", true); execCommand("at+cmgs=\"" + destNumber + "\"", "Setting destination " + "number and opening text input", true); execCommand(message + "\u001A", "Seeting SMS text and sending message", true); } public static SMSReceived[] buildSmsListFromString(String completeList) { Vector v = new Vector(); StringTokenizer st = new StringTokenizer(completeList, "\r\n"); while (st.hasMoreTokens()) { String firstLine = st.nextToken(); if (!firstLine.equals("OK")) { String secondLine = st.nextToken(); SMSReceived sms = new SMSReceived(firstLine, secondLine); v.add(sms); } } SMSReceived[] result = new SMSReceived[v.size()]; int i = 0; for (Enumeration e = v.elements(); e.hasMoreElements(); ) result[i++] = (SMSReceived)e.nextElement(); return result; } private SMSReceived[] getMessages(int newOrOld) throws SmsException, InterruptedException, IOException { resetModem(); String completeList = execCommand("AT+CMGL=" + newOrOld, "Retrieving messages", true); return buildSmsListFromString(completeList); } public SMSReceived[] getNewMessages() throws SmsException, InterruptedException, IOException { return getMessages(0); } public SMSReceived[] getAllMessages() throws SmsException, InterruptedException, IOException { return getMessages(1); } public void deleteSms(int index) throws SmsException, InterruptedException, IOException { execCommand("AT+CMGD=" + index, "Deleting sms " + index, true); } public static void main(String[] args) { try { /* Only list COM ports */ for(Enumeration e = CommPortIdentifier.getPortIdentifiers(); e.hasMoreElements();) { CommPortIdentifier curr = (CommPortIdentifier)e.nextElement(); System.out.println(curr.getName() + ", owner: " + curr.getCurrentOwner()); } SMS stg = new SMS("COM5"); SMS.debug = false; /* This is my phone number, please use yours :-) */ String destNumber = new String("+393383730860"); /* This is a valid SMSC for Vodafone Italy */ String SMSCnumber = "+393492000200"; String message = "INIZIOfoivafvòjae0oivjaeroikvòljnasfo,vnaòlrmvanbvsd" + "lmajro.inevmòakvafoòsivoaòlijvaoiòw,kmvalhvoòpsfi9,mviwdmvòoasifmnvo" + "òafimòovaifmvoòaifmvaòosimjvò12ALDO12345"; //stg.sendSms(SMSCnumber, destNumber, message); /* Get new messages */ SMSReceived[] newMex = stg.getNewMessages(); if(newMex.length > 0) { System.out.println("********New messages*******"); for(int i=0; i msgIndex) { stg.deleteSms(msgIndex); System.out.println("Message " + msgIndex + " deleted"); } } catch(Exception ex) { ex.printStackTrace(); } } }