短信猫

xiaoxiao2021-02-28  209

一、SMSLib简介

SMSLib是一个开放源代码的短信猫二次开发包,有Java和.Net两个版本,目前最新版为v3.5.2。

                                                                                                                                                                       图1-1

二、Window平台

1、在smslib官网下载“SMSLib for Java v3.5.2”开发包,并解压,目录结构如下图所示:

                                                                        图2-1

                                                                        图2-2

lib:存放二次开发包(smslib-3.5.2.jar)和运行时的依赖包(slf4j、log4j、commons-net、jsmpp等)(重要)

dist:存放短信猫服务开发包(smsserver-3.5.2.jar),该包包括了smslib-3.5.2.jar中的所有核心类。如果是将短信猫作为服务的方式部署,不需要额外写代码开发短信发送和接收的接口,直接部署短信服务即可,详细的步聚,可以参考《短信猫服务安装与配置指南》。(重要)

doc:smslib介绍、使用指南、smsserver安装与配置等文档(重要)

javadoc:二次开发包API

src:存放二次开发包源码和示例源码

misc:smslib日志(log4j)配置配置模板、smsserver数据库建库脚本及服务接口等文件

build:项目管理相关文件(不重要)

2、下载SUN JavaComm v2 (Win32)动态库,并解压,目录结构如下图所示:

                                                                        图3-1

3、运行环境配置

复制“图3-1”中javax.comm.properties文件到%JAVA_HOME%\jre\lib目录下,win32com.dll文件到%JAVA_HOME%\jre\bin目录下复制“图3-1”中comm.jar和图2-2中所有jar文件到CLASSPATH目录下(如果是用eclipse等IDE工具,将这些jar包导入到工程中)

       注意: win32com.dll只支持32位jdk

4、运行示例程序并测试       修改图2-1中src\java\examples\modem目录下的SendMessage.java和ReadMessages.java程序发送短信的参数配置,编译并运行。如下图所示: [java]  view plain copy // SendMessage.java - Sample application.   // 短信发送测试程序   // This application shows you the basic procedure for sending messages.   // You will find how to send synchronous and asynchronous messages.   //   // For asynchronous dispatch, the example application sets a callback   // notification, to see what's happened with messages.      package examples.modem;      import org.smslib.AGateway;   import org.smslib.IOutboundMessageNotification;   import org.smslib.Library;   import org.smslib.OutboundMessage;   import org.smslib.Service;   import org.smslib.modem.SerialModemGateway;      public class SendMessage   {       public void doIt() throws Exception       {           OutboundNotification outboundNotification = new OutboundNotification();           System.out.println("Example: Send message from a serial gsm modem.");           System.out.println(Library.getLibraryDescription());           System.out.println("Version: " + Library.getLibraryVersion());           /*          modem.com1:网关ID(即短信猫端口编号)          COM4:串口名称(在window中以COMXX表示端口名称,在linux,unix平台下以ttyS0-N或ttyUSB0-N表示端口名称),通过端口检测程序得到可用的端口          115200:串口每秒发送数据的bit位数,必须设置正确才可以正常发送短信,可通过程序进行检测。常用的有115200、9600          Huawei:短信猫生产厂商,不同的短信猫生产厂商smslib所封装的AT指令接口会不一致,必须设置正确.常见的有Huawei、wavecom等厂商          最后一个参数表示设备的型号,可选          */           SerialModemGateway gateway = new SerialModemGateway("modem.com1""COM4"115200"Huawei""");           gateway.setInbound(true);   //设置true,表示该网关可以接收短信,根据需求修改           gateway.setOutbound(true);//设置true,表示该网关可以发送短信,根据需求修改           gateway.setSimPin("0000");//sim卡锁,一般默认为0000或1234           // Explicit SMSC address set is required for some modems.           // Below is for VODAFONE GREECE - be sure to set your own!           gateway.setSmscNumber("+306942190000");//短信服务中心号码           Service.getInstance().setOutboundMessageNotification(outboundNotification); //发送短信成功后的回调函方法           Service.getInstance().addGateway(gateway);  //将网关添加到短信猫服务中           Service.getInstance().startService();   //启动服务,进入短信发送就绪状态           System.out.println();           //打印设备信息           System.out.println("Modem Information:");           System.out.println("  Manufacturer: " + gateway.getManufacturer());           System.out.println("  Model: " + gateway.getModel());           System.out.println("  Serial No: " + gateway.getSerialNo());           System.out.println("  SIM IMSI: " + gateway.getImsi());           System.out.println("  Signal Level: " + gateway.getSignalLevel() + " dBm");           System.out.println("  Battery Level: " + gateway.getBatteryLevel() + "%");           System.out.println();           // Send a message synchronously.           OutboundMessage msg = new OutboundMessage("306974000000""Hello from SMSLib!");    //参数1:手机号码 参数2:短信内容           Service.getInstance().sendMessage(msg); //执行发送短信           System.out.println(msg);           // Or, send out a WAP SI message.           //OutboundWapSIMessage wapMsg = new OutboundWapSIMessage("306974000000",     //new URL("http://www.smslib.org/"), "Visit SMSLib now!");           //Service.getInstance().sendMessage(wapMsg);           //System.out.println(wapMsg);           // You can also queue some asynchronous messages to see how the callbacks           // are called...           //msg = new OutboundMessage("309999999999", "Wrong number!");           //srv.queueMessage(msg, gateway.getGatewayId());           //msg = new OutboundMessage("308888888888", "Wrong number!");           //srv.queueMessage(msg, gateway.getGatewayId());           System.out.println("Now Sleeping - Hit <enter> to terminate.");           System.in.read();           Service.getInstance().stopService();       }          /*       短信发送成功后,调用该接口。并将发送短信的网关和短信内容对象传给process接口      */       public class OutboundNotification implements IOutboundMessageNotification       {           public void process(AGateway gateway, OutboundMessage msg)           {               System.out.println("Outbound handler called from Gateway: " + gateway.getGatewayId());               System.out.println(msg);           }       }          public static void main(String args[])       {           SendMessage app = new SendMessage();           try           {               app.doIt();           }           catch (Exception e)           {               e.printStackTrace();           }       }   }   [java]  view plain copy // ReadMessages.java - Sample application.   // 短信读取程序   // This application shows you the basic procedure needed for reading   // SMS messages from your GSM modem, in synchronous mode.   //   // Operation description:   // The application setup the necessary objects and connects to the phone.   // As a first step, it reads all messages found in the phone.   // Then, it goes to sleep, allowing the asynchronous callback handlers to   // be called. Furthermore, for callback demonstration purposes, it responds   // to each received message with a "Got It!" reply.   //   // Tasks:   // 1) Setup Service object.   // 2) Setup one or more Gateway objects.   // 3) Attach Gateway objects to Service object.   // 4) Setup callback notifications.   // 5) Run      package examples.modem;      import java.util.ArrayList;   import java.util.List;   import javax.crypto.spec.SecretKeySpec;   import org.smslib.AGateway;   import org.smslib.AGateway.GatewayStatuses;   import org.smslib.AGateway.Protocols;   import org.smslib.ICallNotification;   import org.smslib.IGatewayStatusNotification;   import org.smslib.IInboundMessageNotification;   import org.smslib.IOrphanedMessageNotification;   import org.smslib.InboundMessage;   import org.smslib.InboundMessage.MessageClasses;   import org.smslib.Library;   import org.smslib.Message.MessageTypes;   import org.smslib.Service;   import org.smslib.crypto.AESKey;   import org.smslib.modem.SerialModemGateway;      public class ReadMessages   {       public void doIt() throws Exception       {           // Define a list which will hold the read messages.           List<InboundMessage> msgList;           // Create the notification callback method for inbound & status report           // messages.           InboundNotification inboundNotification = new InboundNotification();           // Create the notification callback method for inbound voice calls.           CallNotification callNotification = new CallNotification();           //Create the notification callback method for gateway statuses.           GatewayStatusNotification statusNotification = new GatewayStatusNotification();           OrphanedMessageNotification orphanedMessageNotification = new OrphanedMessageNotification();           try           {               System.out.println("Example: Read messages from a serial gsm modem.");               System.out.println(Library.getLibraryDescription());               System.out.println("Version: " + Library.getLibraryVersion());               // Create the Gateway representing the serial GSM modem.               SerialModemGateway gateway = new SerialModemGateway("modem.com4""COM4"115200"Huawei""E160");               // Set the modem protocol to PDU (alternative is TEXT). PDU is the default, anyway...               gateway.setProtocol(Protocols.PDU);               // Do we want the Gateway to be used for Inbound messages?               gateway.setInbound(true);               // Do we want the Gateway to be used for Outbound messages?               gateway.setOutbound(true);               // Let SMSLib know which is the SIM PIN.               gateway.setSimPin("0000");               // Set up the notification methods.               Service.getInstance().setInboundMessageNotification(inboundNotification);               Service.getInstance().setCallNotification(callNotification);               Service.getInstance().setGatewayStatusNotification(statusNotification);               Service.getInstance().setOrphanedMessageNotification(orphanedMessageNotification);               // Add the Gateway to the Service object.               Service.getInstance().addGateway(gateway);               // Similarly, you may define as many Gateway objects, representing               // various GSM modems, add them in the Service object and control all of them.               // Start! (i.e. connect to all defined Gateways)               Service.getInstance().startService();               // Printout some general information about the modem.               System.out.println();               System.out.println("Modem Information:");               System.out.println("  Manufacturer: " + gateway.getManufacturer());               System.out.println("  Model: " + gateway.getModel());               System.out.println("  Serial No: " + gateway.getSerialNo());               System.out.println("  SIM IMSI: " + gateway.getImsi());               System.out.println("  Signal Level: " + gateway.getSignalLevel() + " dBm");               System.out.println("  Battery Level: " + gateway.getBatteryLevel() + "%");               System.out.println();               // In case you work with encrypted messages, its a good time to declare your keys.               // Create a new AES Key with a known key value.                // Register it in KeyManager in order to keep it active. SMSLib will then automatically               // encrypt / decrypt all messages send to / received from this number.               Service.getInstance().getKeyManager().registerKey("+306948494037",    new AESKey(new SecretKeySpec("0011223344556677".getBytes(), "AES")));               // Read Messages. The reading is done via the Service object and               // affects all Gateway objects defined. This can also be more directed to a specific               // Gateway - look the JavaDocs for information on the Service method calls.               msgList = new ArrayList<InboundMessage>();               Service.getInstance().readMessages(msgList, MessageClasses.ALL);               for (InboundMessage msg : msgList)                   System.out.println(msg);               // Sleep now. Emulate real world situation and give a chance to the notifications               // methods to be called in the event of message or voice call reception.               System.out.println("Now Sleeping - Hit <enter> to stop service.");               System.in.read();               System.in.read();           }           catch (Exception e)           {               e.printStackTrace();           }           finally           {               Service.getInstance().stopService();           }       }          public class InboundNotification implements IInboundMessageNotification       {           public void process(AGateway gateway, MessageTypes msgType, InboundMessage msg)           {               if (msgType == MessageTypes.INBOUND) System.out.println(">>> New Inbound message detected from Gateway: "    + gateway.getGatewayId());               else if (msgType == MessageTypes.STATUSREPORT) System.out.println(">>> New Inbound Status " +    "Report message detected from Gateway: " + gateway.getGatewayId());               System.out.println(msg);           }       }          public class CallNotification implements ICallNotification       {           public void process(AGateway gateway, String callerId)           {               System.out.println(">>> New call detected from Gateway: " + gateway.getGatewayId() + " : " + callerId);           }       }          public class GatewayStatusNotification implements IGatewayStatusNotification       {           public void process(AGateway gateway, GatewayStatuses oldStatus, GatewayStatuses newStatus)           {               System.out.println(">>> Gateway Status change for " + gateway.getGatewayId() + ", OLD: " + oldStatus + " -> NEW: " + newStatus);           }       }          public class OrphanedMessageNotification implements IOrphanedMessageNotification       {           public boolean process(AGateway gateway, InboundMessage msg)           {               System.out.println(">>> Orphaned message part detected from " + gateway.getGatewayId());               System.out.println(msg);               // Since we are just testing, return FALSE and keep the orphaned message part.               return false;           }       }          public static void main(String args[])       {           ReadMessages app = new ReadMessages();           try           {               app.doIt();           }           catch (Exception e)           {               e.printStackTrace();           }       }   }   三、Linux、Unix、Solaris平台 与window平台不同的地方就在于动态库和二次开发包不一致,其它基本类似 rxtx与comm的编码方式是不一样的。 1、下载 RxTx v2.1.7 R2 2、解压,目录结构如下图所示:                                                                         图4-1 3、运行环境配置 复制图4-1中Linux目录下的librxtxSerial.so文件至$JAVA_HOME/jre/lib/$(ARCH)/目录下,复制RXTXcomm.jar到应用程序的CLASSPATH或$JAVA_HOME/jre/lib/ext目录下复制图3-1中的javax.comm.properties文件至$JAVA_HOME/jre/lib目录下,并将文件中的Driver=com.sun.comm.Win32Driver改成Driver=gnu.io.CommDriver。文件内容如下图所示: 4、修改示例程序,编译并运行 四、短信猫设备可用端口检测程序 [java]  view plain copy import gnu.io.*;   import java.util.*;   import java.io.*;      public class CommTest   {       static CommPortIdentifier portId;       static Enumeration portList;       static int bauds[] = { 96001920057600115200 };    //检测端口所支持的波特率          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 < bauds.length; 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)                               {                                   System.out.println("  没有发现设备!");                               }                           }                           else System.out.println("  没有发现设备!");                           serialPort.close();                       }                       catch (Exception e)                       {                           System.out.println("  没有发现设备!");                       }                   }               }           }       }   }  

五、短信猫设备使用minicom检测

1、linux下端口配置

软件安装完毕后,采用minicom进行配置

执行sudo minicom -s,进入配置界面,

在第三项『串口配置』,设置端口为全面查询到的端口,速率是9600(根据短信猫设备来定,不同的厂家可能会不一样)

Serial Device :/dev/ttyS1(此为串口端口,可以在ttyS0~~ttyS4中挨个试)

然后在主菜单Save setup as dfl

可选择Exit推出配置进入minicom,就可以使用at命令测试配置是否成功;也可选择Exit from Minicom推出minicom。

接下在再次执行minicom,进入主界面,这时候应该就可以输入AT指令了。要注意的是,我是重新插拔了一下短信猫才成功连上的

六、minicom使用方法

1、启动minicom命令

   sudo miniscom

2、输入命令

   同时按Ctrl+a 后按e键,不按e键不能输入命令。

   输入at回车,会输出OK。证明短信猫连接成功。如果没有返回可以修改端口再试

  at发短信命令 at+cmgs=手机号码

  ctrl+z发送短信

3、退出命令

   同时按Ctrl+a 后按x键

七、Linux虚拟机需要注意是否共享串口

    配置成功后会在“vm”菜单中看到共享的端口 八、java环境变量

注意事项:

1、使用smslib库之前,如果你的设备是usb数据线,先检查系统中该设备驱动程序是否已安装,在window环境下,厂商一般会提供设备的驱动程序,在linux环境下,内核2.6.32或以上版本,预装了常用设备的USB转串口驱动,如果系统未自动识别该设备,就需要自行安装该设备的驱动程序了。

2、在开发过程中,org.smslib.TimeoutException: No response from device是最常遇到的一个异常,解决方案请参考:短信猫JAVA二次开发包SMSLib,org.smslib.TimeoutException: No response from device解决方案

转载请注明原文地址: https://www.6miu.com/read-80785.html

最新回复(0)