本文原创,转载请注明出处
参考文档:
https://blog.csdn.net/a_tu_/article/details/47808017
https://blog.csdn.net/zxl782340680/article/details/78905182
https://blog.csdn.net/chenwenjun1/article/details/82967872
http://rxtx.qbang.org/wiki/index.php/Download#x64_Binaries
1. 问题No response from device
bug: org.smslib.TimeoutException: No response from device
参考网上各种解决bug,没有一个能解决问题。大部分都说要按照下面两种方式配置
1. 要设置Service.getInstance().S.SERIAL_POLLING = true;//显示启用轮循模式
2. 创建串口网关对象时,是否设置了正确的短信猫设备生产厂商
SerialModemGateway gateway = new SerialModemGateway("modem.com1", "/dev/ttyUSB1", 9600, "Wavecom", "型号");
但实际上,这两种方式都解决不了问题;
解决办法看文章最后
2. 资源
链接:https://pan.baidu.com/s/1cZCcNTUQlru3BvqBUtnlkA
提取码:tfj2
复制这段内容后打开百度网盘手机App,操作更方便哦
下载开发依赖包,依据自己的电脑是64位还是32位,下载对应的包
http://rxtx.qbang.org/wiki/index.php/Download#Known_RXTX_forks
http://fizzed.com/oss/rxtx-for-java
下载下来解压,如下图所示:
3. 环境配置
1. 看Install.txt文档,按下面的要求设置,将对应的文件放入对应的位置:
For a JDK installation:
Copy RXTXcomm.jar --->
Copy rxtxSerial.dll --->
Copy rxtxParallel.dll --->
2. 项目依赖jar包
4. 测试代码
package com.sms.common;
import org.smslib.helper.CommPortIdentifier;
import org.smslib.helper.SerialPort;
import java.io.*;
import java.util.Enumeration;
/**
* 检测设备
*/
public class CommTest {
private static CommPortIdentifierportId;
@SuppressWarnings("rawtypes")
private static EnumerationportList;
//static int bauds[] = { 9600, 19200, 57600, 115200 };
private static int bauds[] = {9600,115200 };
public static void main(String[] args) {
portList = CommPortIdentifier.getPortIdentifiers();
System.out.println("金笛短信设备端口连接测试...");
while (portList.hasMoreElements()) {
portId = (CommPortIdentifier)portList.nextElement();
if (portId.getPortType() == CommPortIdentifier.PORT_SERIAL) {
System.out.println("找到串口: " +portId.getName());
for (int i =0; i
System.out.print(" Trying at " +bauds[i] +"...");
try {
SerialPort serialPort;
InputStream inStream;
OutputStream outStream;
int c;
String response;
serialPort = (SerialPort)portId.open("SMSLibCommTester",1971);
//serialPort.setFlowControlMode(SerialPort.FLOWCONTROL_RTSCTS_IN);
serialPort.setSerialPortParams(bauds[i], SerialPort.DATABITS_8, SerialPort.STOPBITS_1, SerialPort.PARITY_NONE);
inStream = serialPort.getInputStream();
outStream = serialPort.getOutputStream();
serialPort.enableReceiveTimeout(1000);
c = inStream.read();
while (c != -1) {
c = inStream.read();
}
outStream.write('A');
outStream.write('T');
outStream.write('\r');
try {
Thread.sleep(1000);
}catch (Exception e) {
}
response ="";
c = inStream.read();
while (c != -1) {
response += (char) c;
c = inStream.read();
}
if (response.indexOf("OK") >=0) {
try {
System.out.print(" 获取设备信息...");
outStream.write('A');
outStream.write('T');
outStream.write('+');
outStream.write('C');
outStream.write('G');
outStream.write('M');
outStream.write('M');
outStream.write('\r');
response ="";
c = inStream.read();
while (c != -1) {
response += (char) c;
c = inStream.read();
}
System.out.println(" 发现设备: " + response.replaceAll("\\s+OK\\s+","").replaceAll("\n","").replaceAll("\r",""));
}catch (Exception e) {
e.printStackTrace();
System.out.println(" 没有发现设备!");
}
}else {
System.out.println(" 没有发现设备!");
};
serialPort.close();
inStream.close();
outStream.close();
}catch (Exception e) {
e.printStackTrace();
System.out.println(" 没有发现设备 end!");
}
}
}
}
}
}
注://serialPort.setFlowControlMode(SerialPort.FLOWCONTROL_RTSCTS_IN);//这行代码注释掉就能正常运行了。
4. 发送短信代码
package com.sms.common;
import java.time.LocalDateTime;
import org.smslib.Message;
import org.smslib.OutboundMessage;
import org.smslib.Service;
import org.smslib.modem.SerialModemGateway;
/*1、是否启用轮循模式?
方式1)、在jvm中,添加-Dsmslib.serial.polling启动参数
方式2)、在JAVA代码中,在调用startService之前,显示启用轮循模式*/
public class SendGsm {
public static boolean SMSReminds(String phone, String content)throws Exception {
// 1、连接网关的id
// 2、com口名称,如COM1或/dev/ttyS1(根据实际情况修改
// 3、串口波特率,如9600(根据实际情况修改)
// 4、开发商Huawei_E160 Huawei/ME909
// 5、型号M1806-ME
SerialModemGateway gateway =new SerialModemGateway("model.com5","COM5",115200,"Huawei","");
//SerialModemGateway gateway = new SerialModemGateway("smsTest_COM5", "COM5", 115200, "Huawei", "");
// 设置true,表示该网关可以接收短信
gateway.setInbound(true);
// 设置true,表示该网关可以发送短信
gateway.setOutbound(true);
//gateway.setCustomInitString("AT");
// -----------------创建发送短信的服务(它是单例的)----------------
Service service = Service.getInstance();
//Service.getInstance().S.SERIAL_POLLING = true;
boolean result=false;
try {
// ---------------------- 将设备加到服务中----------------------
service.addGateway(gateway);
// ------------------------- 启动服务-------------------------
service.startService();
System.out.println("服务启动成功");
// ------------------------- 发送短信-------------------------
OutboundMessage msg =new OutboundMessage(phone, content);
msg.setEncoding(Message.MessageEncodings.ENCUCS2);
System.out.println("startDate=====" + LocalDateTime.now().toString());
result = service.sendMessage(msg);
System.out.println("endDate=====" + LocalDateTime.now().toString());
// ------------------------- 关闭服务-------------------------
service.stopService();
service.removeGateway(gateway);
}catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
service.stopService();
service.removeGateway(gateway);
return false;
}
return result;
}
public static void main(String[] args) {
try {
boolean sendResult =SMSReminds("10086","abcd大小多少!");
System.out.println("sendResult = [" + sendResult +"]");
}catch (Exception e) {
e.printStackTrace();
}
}
}
5. 解决bug:No response from device
凑巧发现了无法连接设备的原因,因此注销掉不必要的代码即可:
1. 建立和包名同样的路径
2. 将代码复制到包下即可
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//
package org.smslib.modem;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.StringTokenizer;
import org.smslib.GatewayException;
import org.smslib.Service;
import org.smslib.helper.CommPortIdentifier;
import org.smslib.helper.Logger;
import org.smslib.helper.SerialPort;
import org.smslib.helper.SerialPortEvent;
import org.smslib.helper.SerialPortEventListener;
import org.smslib.threading.AServiceThread;
class SerialModemDriverextends AModemDriverimplements SerialPortEventListener {
private StringcomPort;
private int baudRate;
private CommPortIdentifierportId;
private SerialPortserialPort;
private InputStreamin;
private OutputStreamout;
private SerialModemDriver.PortReaderportReader;
protected SerialModemDriver(ModemGateway myGateway, String deviceParms) {
super(myGateway, deviceParms);
StringTokenizer tokens =new StringTokenizer(deviceParms,":");
this.setComPort(tokens.nextToken());
this.setBaudRate(Integer.parseInt(tokens.nextToken()));
this.setSerialPort((SerialPort)null);
}
@Override
protected void connectPort()throws GatewayException, IOException, InterruptedException {
if (Service.getInstance().getSettings().SERIAL_NOFLUSH) {
Logger.getInstance().logInfo("Comm port flushing is disabled.", (Exception)null,this.getGateway().getGatewayId());
}
if (Service.getInstance().getSettings().SERIAL_POLLING) {
Logger.getInstance().logInfo("Using polled serial port mode.", (Exception)null,this.getGateway().getGatewayId());
}
try {
Logger.getInstance().logInfo("Opening: " +this.getComPort() +" @" +this.getBaudRate(), (Exception)null,this.getGateway().getGatewayId());
CommPortIdentifier.getPortIdentifiers();
this.setPortId(CommPortIdentifier.getPortIdentifier(this.getComPort()));
this.setSerialPort(this.getPortId().open("org.smslib",1971));
this.setIn(this.getSerialPort().getInputStream());
this.setOut(this.getSerialPort().getOutputStream());
if (!Service.getInstance().getSettings().SERIAL_POLLING) {
this.getSerialPort().notifyOnDataAvailable(true);
this.getSerialPort().notifyOnOutputEmpty(true);
}
if (!Service.getInstance().getSettings().SERIAL_NOEVENTS) {
this.getSerialPort().notifyOnBreakInterrupt(true);
this.getSerialPort().notifyOnFramingError(true);
this.getSerialPort().notifyOnOverrunError(true);
this.getSerialPort().notifyOnParityError(true);
}else {
Logger.getInstance().logInfo("Skipping registration of serial port events!", (Exception)null, (String)null);
}
/* if (Service.getInstance().getSettings().SERIAL_RTSCTS_OUT) {
this.getSerialPort().setFlowControlMode(SerialPort.FLOWCONTROL_RTSCTS_IN | SerialPort.FLOWCONTROL_RTSCTS_OUT);
} else {
this.getSerialPort().setFlowControlMode(SerialPort.FLOWCONTROL_RTSCTS_IN);
}*/
this.getSerialPort().addEventListener(this);
this.getSerialPort().setSerialPortParams(this.getBaudRate(), SerialPort.DATABITS_8, SerialPort.STOPBITS_1, SerialPort.PARITY_NONE);
this.getSerialPort().setInputBufferSize(Service.getInstance().getSettings().SERIAL_BUFFER_SIZE);
this.getSerialPort().setOutputBufferSize(Service.getInstance().getSettings().SERIAL_BUFFER_SIZE);
this.getSerialPort().enableReceiveThreshold(1);
this.getSerialPort().enableReceiveTimeout(Service.getInstance().getSettings().SERIAL_TIMEOUT);
if (Service.getInstance().getSettings().SERIAL_POLLING) {
this.setPortReader(new SerialModemDriver.PortReader("PortReader() [" +this.getComPort() +"]", Service.getInstance().getSettings().SERIAL_POLLING_INTERVAL));
}
}catch (Exception var2) {
throw new GatewayException("Comm library exception: " + var2.getMessage());
}
}
@Override
protected void disconnectPort()throws IOException, InterruptedException {
synchronized(this.getSYNCReader()) {
if (Service.getInstance().getSettings().SERIAL_POLLING &&this.getPortReader() !=null) {
this.getPortReader().cancel();
this.setPortReader((SerialModemDriver.PortReader)null);
}
if (this.getSerialPort() !=null) {
this.getSerialPort().close();
}
Logger.getInstance().logInfo("Closing: " +this.getComPort() +" @" +this.getBaudRate(), (Exception)null,this.getGateway().getGatewayId());
}
}
@Override
protected void clear()throws IOException {
while(this.portHasData()) {
this.read();
}
}
@Override
protected boolean portHasData()throws IOException {
return this.getIn().available() >0;
}
@Override
public void serialEvent(SerialPortEvent event) {
int eventType = event.getEventType();
if (eventType == SerialPortEvent.OE) {
Logger.getInstance().logError("Overrun Error!", (Exception)null,this.getGateway().getGatewayId());
}else if (eventType == SerialPortEvent.FE) {
Logger.getInstance().logError("Framing Error!", (Exception)null,this.getGateway().getGatewayId());
}else if (eventType == SerialPortEvent.PE) {
Logger.getInstance().logError("Parity Error!", (Exception)null,this.getGateway().getGatewayId());
}else if (eventType == SerialPortEvent.DATA_AVAILABLE && !Service.getInstance().getSettings().SERIAL_POLLING) {
synchronized(this.getSYNCReader()) {
this.setDataReceived(true);
this.getSYNCReader().notifyAll();
}
}
}
@Override
public void write(char c)throws IOException {
this.getOut().write(c);
if (!Service.getInstance().getSettings().SERIAL_NOFLUSH) {
this.getOut().flush();
}
}
@Override
public void write(byte[] s)throws IOException {
if (Service.getInstance().getSettings().SERIAL_BUFFER_CHUNK ==0) {
this.getOut().write(s);
}else {
int offset =0;
int left = s.length;
while(left >0) {
int i = left > Service.getInstance().getSettings().SERIAL_BUFFER_CHUNK ? Service.getInstance().getSettings().SERIAL_BUFFER_CHUNK : left;
this.getOut().write(s, offset, i);
offset += i;
left -= i;
try {
Thread.sleep((long)Service.getInstance().getSettings().SERIAL_BUFFER_CHUNK_DELAY);
}catch (InterruptedException var6) {
;
}
}
}
if (!Service.getInstance().getSettings().SERIAL_NOFLUSH) {
this.getOut().flush();
}
}
@Override
protected int read()throws IOException {
return this.getIn().read();
}
SerialModemDriver.PortReader getPortReader() {
return this.portReader;
}
void setPortReader(SerialModemDriver.PortReader myPortReader) {
this.portReader = myPortReader;
}
String getComPort() {
return this.comPort;
}
void setComPort(String myComPort) {
this.comPort = myComPort;
}
int getBaudRate() {
return this.baudRate;
}
void setBaudRate(int myBaudRate) {
this.baudRate = myBaudRate;
}
CommPortIdentifier getPortId() {
return this.portId;
}
void setPortId(CommPortIdentifier myPortId) {
this.portId = myPortId;
}
SerialPort getSerialPort() {
return this.serialPort;
}
void setSerialPort(SerialPort mySerialPort) {
this.serialPort = mySerialPort;
}
InputStream getIn() {
return this.in;
}
void setIn(InputStream myIn) {
this.in = myIn;
}
OutputStream getOut() {
return this.out;
}
void setOut(OutputStream myOut) {
this.out = myOut;
}
private class PortReaderextends AServiceThread {
public PortReader(String name,int delay) {
super(name, delay,0,true);
}
@Override
public void process()throws Exception {
if (SerialModemDriver.this.portHasData()) {
synchronized(SerialModemDriver.this.getSYNCReader()) {
SerialModemDriver.this.setDataReceived(true);
SerialModemDriver.this.getSYNCReader().notifyAll();
}
}
}
}
}
黑体的,就是被注释掉的,就是不必要的代码,不要问我为什么,我也不知道。完成这个任务,我是靠向主耶稣祷告,加上勤奋努力,试出来的。
知道原因,也没什么用,因为又不是做硬件开发的。人生不过虚空,不要把时间浪费在这些东西上面。要追求真理,得着生命。而耶稣就是真理,道路,实际。除了他,一切都是虚空,如捕风捉影,因为你面对的不仅是苦难,而结局却是死亡。
哲学为什么没用,因为哲学是在“知识树”上,不在“生命树”上,学的越多,越觉得虚空。它无法解答“我是谁,我从哪里来,到哪里去”
约翰福音 6:39
那差我来者的意思,就是凡祂所赐给我的,叫我一个也不失落,在末日却叫他复活。
约翰福音 6:40
因为我父的意思,是叫一切看见子而信入祂的人,得着永远的生命,并且在末日我要叫他复活。
6. 运行结果证明:
6.1 设备测试代码
6.2 发送短信测试结果
代码:
boolean sendResult =SMSReminds("132*******9","!#$¥**——_MMMabcd大小多少!");
System.out.println("sendResult = [" + sendResult +"]");
结果: