首先确定短信猫正常连接到主机,并安装SIM卡。
先用超级终端测试短息猫能不能用。
安装minicom:
#sudo apt-get
install minicom
安装完成后,执行
#sudo minicom -s
使用光标上下选择:Serial port setup,如下图
按A,设置端口号,COM1对应/dev/ttyS0,
按E,修改波特率、奇偶校验等,我的短信猫波特率用的是默认,
按F,将Hardware
Flow Control变为NO,
按Enter键,返回,
选择Save setup as
dfl,即作为默认配置,
选择Exit,进入到Minicom:
输入at,按Enter,若打印出ok,则正常。
输入at+cmgf=1,设置短信格式,1是文本格式,0是PDF格式,
输入at+cmgs=xxxxx,接收手机号码,Enter,接着输入内容,按Ctrl+Z,等待,
界面打印OK,手机接收短信。
超级终端成功,接下来调试Java代码,我使用的jar包是jssc-2.8.0.jar
下面是代码:
package com.sendSMS; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.IOException; import jssc.SerialPort; import jssc.SerialPortEvent; import jssc.SerialPortEventListener; import jssc.SerialPortException; import jssc.SerialPortList; public class Sender { private String msgCenterPhone; private String portName; private int baud; private int parity; private int stop; private int data; private int gsmType; private SerialPort serialPort; /** AT+CMGS= */ public final static byte[] SMS_STRUCTOR = { 0x41, 0x54, 0x2B, 0x43, 0x4D, 0x47, 0x53, 0x3D}; /** AT+CMGF=0 */ public final static byte[] SMS_PDU_HEADER = { 0x41, 0x54, 0x2B, 0x43, 0x4D, 0x47, 0x46, 0x3D, 0x30}; public final static byte[] SMS_HEADER_START = { 0x41, 0x54, 0x2B, 0x43, 0x4D, 0x47, 0x53, 0x3D}; public final static byte[] SMS_HEADER_END = { 0x0D}; public final static byte[] SMS_CONTENT_END = { 0x1A}; public void setCenterPhone(String phoneNumber) { this.msgCenterPhone = phoneNumber; } public void setSerialPort(String portName) { this.portName = portName; } public void setParams(int baudRate, int parity, int stop, int data) { this.baud = baudRate; this.parity = parity; this.stop = stop; this.data = data; } public void setGSMType(int gsmType) { this.gsmType = gsmType; } public Sender() { //msgCenterPhone = msgCenterPhone.trim(); portName = "COM10"; baud = 115200; parity = 0; stop = 1; data = 8; gsmType = 2; } public Sender(String phoneNo, String portName, int gsmType) { msgCenterPhone = phoneNo; this.portName = portName; baud = 115200; parity = 0; stop = 1; data = 8; this.gsmType = gsmType; } /** * 确认发送格式并发送短信,将长短信分为N条正常短信 * @param mobileSendAlarmInfo * @return 1:发送成功;-1:发送失败 */ public int sendSMS(String destPhone, String content){ /** * 发送成功标志 */ int succeedFlag = 0; serialPort = new SerialPort(this.portName); try { System.out.println("Port opened:" + serialPort.openPort()); System.out.println("Params setted:" + serialPort.setParams(115200, 8 , 1, 0)); System.out.println("Send PDU Header" + serialPort.writeBytes(SMS_PDU_HEADER)); System.out.println("Send Header End" + serialPort.writeBytes(SMS_HEADER_END)); int timeout = 0; while (true) { Thread.sleep(100); byte[] b = new byte[21]; b = serialPort.readBytes(); if (timeout > 50) { System.out.println("Time Out"); return succeedFlag = -1; } if (b == null) { timeout++; continue; } String s = new String(b); if (s.indexOf("OK") != -1) { //‘OK‘ System.out.println("Set PDU Successful!"); break; } } int[] tpduLength = new int[1]; String pack = packStrMessage(destPhone, content, msgCenterPhone, tpduLength); System.out.println("Send Header Start" + serialPort.writeBytes(SMS_HEADER_START)); String strLength = (tpduLength[0] < 100 ? ("0" + Integer.toString(tpduLength[0])) : Integer.toString(tpduLength[0])); System.out.println("Send Header Length"+ serialPort.writeBytes(strLength.getBytes())); System.out.println("Send Header End" + serialPort.writeBytes(SMS_HEADER_END)); Thread.sleep(100); timeout = 0; while (true) { Thread.sleep(100); byte[] b = new byte[21]; b = serialPort.readBytes(); if (timeout > 50) { System.out.println("Time Out"); return succeedFlag = -1; } if (b == null) { timeout++; continue; } String s = new String(b); if (s.indexOf(‘>‘) != -1) { //‘>‘ System.out.println("Title Successful!"); break; } if (s.indexOf("ERROR") != -1) { //‘R‘ System.out.println("Error"); return succeedFlag = -1; } } System.out.println("Send Content: " + serialPort.writeBytes(pack.getBytes())); System.out.println("Send Contend End: " + serialPort.writeBytes(SMS_CONTENT_END)); System.out.println("Send Header End: " + serialPort.writeBytes(SMS_HEADER_END)); timeout = 0; while (true) { Thread.sleep(100); byte[] b = new byte[21]; b = serialPort.readBytes(); if (timeout > 50) { System.out.println("Time Out"); return succeedFlag = -1; } if (b == null) { timeout++; continue; } String s = new String(b); System.out.println(s); //System.exit(0); if (s.indexOf("OK") != -1) { //‘>‘ System.out.println("Content Successful!"); serialPort.closePort(); return succeedFlag = 1; } if (s.indexOf("ERROR") != -1) { //‘R‘ System.out.println("Error"); return succeedFlag = -1; } } } catch (SerialPortException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } return succeedFlag; } private String packStrMessage(String destPhone, String content, String centerPhone, int[] tpduLength) { if (destPhone == null || content == null || centerPhone == null) return ""; //encode the SCA byte[] sca = new byte[3]; sca[0] = (byte) (0x00); sca[1] = (byte) 0x11; sca[2] = (byte) 0x00; //encode TPDU if (!destPhone.startsWith("86")) //add china code 86 to dest phone. 81 为日本的代码 destPhone = "86" + destPhone; int length; int destLength = length = destPhone.length(); if (length % 2 != 0) { //if the dest code is odd , then add ‘F‘ destPhone += "F"; length++; } //content += new String( new char[]{ 0x00 } ); char[] ccontent = content.toCharArray(); int contentLength = ccontent.length; /* Data Length * Dest Phone(encoding) | Data(encoding) * _________|__________ | _____|________ * The tpdu‘ sample byte 11 00 0D 91 68 31 19 01 28 14 F1 00 00 00 05 D4 E2 94 0A 02 * | | | | | | | * | | | TON/NPI | | VP Validity Period * | | Dest Phone Length(Number) | DCS Data Coding Scheme(00-ASCII , 08-UCS2) * | MR Message Reference PID Protocol ID * 8 Bits MTI,RD,VPF,SRR,UDHI,RP,MMS,SRI * so 4 + phoneLength / 2 + 3 + 1 + contenLength is the tpdu length */ byte[] tpdu = new byte[2 + length / 2 + 3 + 1 + contentLength * 2]; int index = 0; tpdu[index++] = (byte) destLength; tpdu[index++] = (byte) 0x91; for (int i = 0; i < length; i += 2) { tpdu[index++] = swap(destPhone.substring(i, i + 2), 16); } tpdu[index++] = 0x00; tpdu[index++] = 0x08; //UCS2 tpdu[index++] = (byte) 0xA7; tpdu[index++] = (byte) (contentLength * 2); for (int i = 0; i < contentLength; i++) { if (i < ccontent.length) { tpdu[index++] = (byte) (ccontent[i] >> 8); tpdu[index++] = (byte) (ccontent[i] & 0x00FF); } else { tpdu[index++] = (byte) (0xFF); tpdu[index++] = (byte) (0xFF); } } //copy sca and tpdu to ret int scaLength = sca.length; tpduLength[0] = tpdu.length + 2; byte[] ret = new byte[scaLength + tpdu.length]; System.arraycopy(sca, 0, ret, 0, scaLength); System.arraycopy(tpdu, 0, ret, scaLength, tpdu.length); String r = new String(); for (int i = 0; i < ret.length; i++) { String s = Integer.toHexString( (char) ret[i] & 0x00ff); if (s.length() == 1) s = "0" + s; r += s; } //System.out.println( r ); return r; } //swap the string and parse it as specail radix byte,just same binary code. //note: the s must has two length string. //eg. swap( "12" , 16 ) will return byte 33 //eg. swap( "68" , 16 ) will return byte -122 public static byte swap(String s, int radix) { byte b1 = Byte.parseByte(s.substring(0, 1), radix); byte b2 = Byte.parseByte(s.substring(1, 2), radix); return (byte) (b2 * radix + b1); } public String toString() { StringBuffer sb = new StringBuffer(); sb.append("The SMS Properties:\n"); sb.append("\nSerial Port=" + serialPort); sb.append("\nBaud=" + baud); sb.append("\nData Bits=" + data); sb.append("\nStop Bit=" + stop); sb.append("\nParity=" + parity); sb.append("\nSMS Center Phone=" + msgCenterPhone); return sb.toString(); } public static void main(String[] args) { Sender sender = new Sender("13800210500", "/dev/ttyS0", 2);//SIM卡所在地短信中心号码、端口号、SIM卡类型默认2即可 int code = sender.sendSMS("xxxxxxxxxxx", "Just for a test");//接收号码、内容 System.out.println(code); } }
编译,还是不行,看下log,好吧,是权限问题,接下来在超级终端中运行:
#sudo chmod 777
/dev/ttyS0
再次编译,手机接到短信了,OK。
在Windows中把端口号换成"COM1"就行了。