11.8.09

Java send SMS via AT Command

เราใช้ AT Command ในการคุยกับอุปกรณ์เคลื่อนที่้ ในโทรศัพท์มือถือทุกวันนี้ก็ได้ implement at command ลงไปเพียงแต่ว่า แต่ละรุ่นก็ใส่ function ลงไปไม่เหมือนกัน ดังนั้นก่อนใช้งานต้องตรวจสอบก่อนว่าโทรศัพท์มือถือที่เราจะติดต่อนั้นรองรับ function ใดบ้าง

การส่ง AT Command ไปให้โทรศัพท์มือถือทำได้ไม่ยาก โดยใช้ Java I/O และจากนั้นส่งคำสั่งผ่าน stream

ตัวอย่างด้านล่างผมเขียนเป็น class util ง่ายๆ ไว้ใช้งานโดยมันสามารถสั่งให้อุปกรณ์มือถือเราส่ง SMS ดังนั้นมันจะเหมือนกับการส่ง SMS ผ่านมือถือปกติแต่จะแตกต่างเพียงแค่ว่าเราสั่งจาก PC ซึ่งมันยืดหยุ่นกว่าในกรณีที่เราจะเขียนโปรแกรมต่อยอดไปอีก


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


class Mobile {

//com.sun.comm.Win32SerialPort
//timeout second / 10
private static final int RESPONSE_TIMEOUT = 50;
//timeout second / 1000
private static final int DEVICE_TIMEOUT = 1000;
private static final String NEWLINE = "\n";
private static final String ENTER = "\r";
private static final String CTRL_Z = "\u001A";
private static final String CONNECTION = "connect";

private InputStream in;
private OutputStream out;

private SerialPort port;
private CommPortIdentifier portID;

public Mobile(String appName, CommPortIdentifier portID) throws IOException, PortInUseException, UnsupportedCommOperationException {
this.portID = portID;
//this.portID.addPortOwnershipListener(new MyCommPortOwnershipListener());
port = (SerialPort) portID.open(appName, DEVICE_TIMEOUT);
port.setSerialPortParams(9600, SerialPort.DATABITS_8, SerialPort.STOPBITS_1, SerialPort.PARITY_NONE);
port.setFlowControlMode(port.FLOWCONTROL_NONE);
in = port.getInputStream();
out = port.getOutputStream();
}

public void close() throws IOException {
in.close();
out.close();
port.close();
}

public static Map<String, CommPortIdentifier> listPort() throws IOException {
Map<String, CommPortIdentifier> listPort = new Hashtable<String, CommPortIdentifier>();
Enumeration portList = CommPortIdentifier.getPortIdentifiers();
while (portList.hasMoreElements()) {
CommPortIdentifier portID = (CommPortIdentifier) portList.nextElement();
listPort.put(portID.getName(), portID);
}
return listPort;
}

public String sendSMS(String tel, String msg) throws IOException, InterruptedException {
String result = null;
sendCommand("AT+CMGF=1");
writeRequest("AT+CMGS=\"" + tel + "\"");
result = sendCommand(msg + CTRL_Z);
return result;
}

public String sendCommand(String cmd) throws IOException, InterruptedException {
writeRequest(cmd);
return readResponse();
}

private void writeRequest(String req) throws IOException {
out.write(new String(req + ENTER).getBytes());
out.flush();
}

private String readResponse() throws IOException, InterruptedException {
String strIn = "";
for (int i=0; i<RESPONSE_TIMEOUT; i++){
int numChars = in.available();
if (numChars > 0){
byte[] bb = new byte[numChars];
in.read(bb, 0, numChars);
strIn += new String(bb);
}
if (strIn.indexOf(">" + ENTER + NEWLINE) != -1) {
break;
}
if (strIn.indexOf("OK" + ENTER + NEWLINE) != -1) {
break;
}
if (strIn.indexOf("ERROR") != -1 &&
strIn.indexOf(ENTER + NEWLINE, strIn.indexOf("ERROR") + 1) != -1) {
break;
}
Thread.sleep(100);
}
return strIn;
}

}
ส่วนตอนเรียกใช้งานก็ง่ายๆ

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

public class Client {

public static void main(String[] args) throws Exception {
//choose port
Map<String, CommPortIdentifier> listPort = Mobile.listPort();
System.out.println(listPort);
Mobile mobile = new Mobile("SMS/GSM Nokia N73", listPort.get("COM12"));
System.out.println(mobile.sendSMS("+66123456789", "Hello World"));
System.out.println("---");
}

}
แน่นอนครับนอกจากส่ง SMS ได้แล้วยังสามารถทำอย่างอื่นได้อีกเช่น รับ SMS, สั่งโทรออก เป็นต้นแต่เราต้องแน่ใจก่อนว่าโทรศัพท์มือถือรองรับ function ดังกล่าว

แล้วเราจะรู้ได้อย่างไรว่าโทรศัพท์มือถือที่เราจะสื่อสารด้วยนี้รองรับ AT Command อะไรบ้าง?
วิธีตรวจสอบง่ายๆ คือการส่งคำสั่ง AT Command ที่เราจะใช้แล้วตามด้วย =? ถ้าตอบกลับมาเป็น ERROR นั่นหมายความว่าไม่อุปกรณ์ที่เราจะติดต่อนั้นไม่รองรับคำสั่งดังกล่าว

นอกจาก AT Command ยังมีวิธีอื่นๆ อีกครับที่สามารถใช้ติดต่อกับโทรศัพท์มือถือได้แต่นั่นก็ขึ้นอยู่กับผู้ผลิตมือถือแต่ละเจ้าด้วย อย่างที่ผมทดสอบผมใช้ Nokia N73 ซึ่งมันไม่รองรับ AT Command (AT+CGMR) ที่จะให้อ่าน SMS เลยต้องไปใช้ Nokia PC Connectivity API แทนครับ

No comments:

Post a Comment