📄 modemgateway.java
字号:
// SMSLib for Java v3
// A Java API library for sending and receiving SMS via a GSM modem
// or other supported gateways.
// Web Site: http://www.smslib.org
//
// SMSLib is distributed under the terms of the Apache License version 2.0
//
// Copyright (C) 2002-2007, Thanasis Delenikas, Athens/GREECE
// Portions Copyright:
// Davide Bettoni, Clusone/ITALY, dbettoni@users.sourceforge.net
// Tomek Cejner, Polland, heretique@users.sourceforge.net
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package org.smslib;
import java.util.*;
import java.util.regex.*;
import java.io.*;
import org.apache.log4j.*;
/**
* Class representing GSM modems or phones. Extends AGateway with modem specific
* operations.
*/
public class ModemGateway extends AGateway
{
private String modemDevice;
private int modemParms;
private String manufacturer;
private String model;
private ModemDriver driver;
private AATHandler atHandler;
private String simPin, simPin2;
private int outMpRefNo;
private List mpMsgList;
private int retriesNoResponse, retriesCmsErrors;
private int delayNoResponse, delayCmsErrors;
private String smscNumber;
ModemGateway(ModemTypes type, String id, String modemDevice, int modemParms, String manufacturer, String model, Logger logger)
{
super(id, logger);
started = false;
this.modemDevice = modemDevice;
this.modemParms = modemParms;
this.manufacturer = manufacturer;
this.model = model;
attributes = AGateway.GatewayAttributes.SEND | AGateway.GatewayAttributes.RECEIVE | AGateway.GatewayAttributes.BIGMESSAGES | AGateway.GatewayAttributes.WAPSI | AGateway.GatewayAttributes.PORTADDRESSING | AGateway.GatewayAttributes.FLASHSMS | AGateway.GatewayAttributes.DELIVERYREPORTS;
if (type == ModemTypes.SERIAL) driver = new SerialModemDriver(this, this.modemDevice + ":" + this.modemParms);
else driver = new IPModemDriver(this, this.modemDevice + ":" + this.modemParms);
atHandler = AATHandler.load(this, this.manufacturer, this.model);
logger.info("Using " + atHandler.description + " AT handler.");
simPin = "";
simPin2 = "";
outMpRefNo = new Random().nextInt();
if (outMpRefNo < 0) outMpRefNo *= -1;
outMpRefNo %= 65536;
mpMsgList = new ArrayList();
retriesNoResponse = 2;
delayNoResponse = 5000;
retriesCmsErrors = 2;
delayCmsErrors = 5000;
smscNumber = "";
}
public void sync() throws IOException, InterruptedException
{
driver.clearBuffer();
}
void startGateway() throws TimeoutException, GatewayException, IOException, InterruptedException
{
logger.info("Starting Gateway: " + gtwId);
driver.connect();
logger.info("Started Gateway: " + gtwId);
super.startGateway();
}
void stopGateway() throws TimeoutException, GatewayException, IOException, InterruptedException
{
logger.info("Stopping Gateway: " + gtwId);
super.stopGateway();
driver.disconnect();
}
void readMessages(List msgList, MessageClasses msgClass) throws TimeoutException, GatewayException, IOException, InterruptedException
{
synchronized (driver.SYNC_Commander)
{
if (protocol == MessageProtocols.PDU) readMessagesPDU(msgList, msgClass, 0);
else if (protocol == MessageProtocols.TEXT) readMessagesTEXT(msgList, msgClass, 0);
}
}
InboundMessage readMessage(String memLoc, int memIndex) throws TimeoutException, GatewayException, IOException, InterruptedException
{
List msgList;
synchronized (driver.SYNC_Commander)
{
msgList = new ArrayList();
readMessages(msgList, MessageClasses.ALL);
for (int i = 0, n = msgList.size(); i < n; i++)
if ((((InboundMessage) msgList.get(i)).getMemIndex() == memIndex) && (((InboundMessage) msgList.get(i)).getMemLocation().equalsIgnoreCase(memLoc))) return (InboundMessage) msgList.get(i);
return null;
}
}
boolean sendMessage(OutboundMessage msg) throws TimeoutException, GatewayException, IOException, InterruptedException
{
synchronized (driver.SYNC_Commander)
{
if (protocol == MessageProtocols.PDU) return sendMessagePDU(msg);
else if (protocol == MessageProtocols.TEXT) return sendMessageTEXT(msg);
else return false;
}
}
boolean deleteMessage(InboundMessage msg) throws TimeoutException, GatewayException, IOException, InterruptedException
{
synchronized (driver.SYNC_Commander)
{
if (msg.getMemIndex() >= 0) return deleteMessage(msg.getMemIndex(), msg.getMemLocation());
else if ((msg.getMemIndex() == -1) && (msg.getMpMemIndex().length() != 0))
{
StringTokenizer tokens = new StringTokenizer(msg.getMpMemIndex(), ",");
while (tokens.hasMoreTokens())
deleteMessage(Integer.parseInt(tokens.nextToken()), msg.getMemLocation());
}
return true;
}
}
boolean deleteMessage(int memIndex, String memLocation) throws TimeoutException, GatewayException, IOException, InterruptedException
{
return atHandler.deleteMessage(memIndex, memLocation);
}
private boolean sendMessagePDU(OutboundMessage msg) throws TimeoutException, GatewayException, IOException, InterruptedException
{
int j, refNo;
String pdu;
boolean ok = false;
atHandler.keepGsmLinkOpen();
if (!msg.isBig())
{
pdu = msg.getPDU(smscNumber, 0, 0);
j = pdu.length();
j /= 2;
if (smscNumber == null)
; // Do nothing on purpose!
else if (smscNumber.length() == 0) j--;
else
{
int smscNumberLen = smscNumber.length();
if (smscNumber.charAt(0) == '+') smscNumberLen--;
if (smscNumberLen % 2 != 0) smscNumberLen++;
int smscLen = (2 + smscNumberLen) / 2;
j = j - smscLen - 1;
}
refNo = atHandler.sendMessage(j, pdu, null, null);
if (refNo >= 0)
{
msg.setGatewayId(gtwId);
msg.setRefNo("" + refNo);
msg.setDispatchDate(new Date());
msg.setMessageStatus(MessageStatuses.SENT);
statistics.outbound++;
ok = true;
}
else
{
msg.setRefNo(null);
msg.setDispatchDate(null);
msg.setMessageStatus(MessageStatuses.FAILED);
ok = false;
}
}
else
{
for (int partNo = 1; partNo <= msg.getNoOfParts(); partNo++)
{
pdu = msg.getPDU(smscNumber, outMpRefNo, partNo);
j = pdu.length();
j /= 2;
if (smscNumber == null)
; // Do nothing on purpose!
else if (smscNumber.length() == 0) j--;
else
{
int smscNumberLen = smscNumber.length();
if (smscNumber.charAt(0) == '+') smscNumberLen--;
if (smscNumberLen % 2 != 0) smscNumberLen++;
int smscLen = (2 + smscNumberLen) / 2;
j = j - smscLen - 1;
}
refNo = atHandler.sendMessage(j, pdu, null, null);
if (refNo >= 0)
{
msg.setGatewayId(gtwId);
msg.setRefNo("" + refNo);
msg.setDispatchDate(new Date());
msg.setMessageStatus(MessageStatuses.SENT);
statistics.outbound++;
ok = true;
}
else
{
msg.setRefNo(null);
msg.setDispatchDate(null);
msg.setMessageStatus(MessageStatuses.FAILED);
}
}
outMpRefNo = (outMpRefNo + 1) % 65536;
}
return ok;
}
private boolean sendMessageTEXT(OutboundMessage msg) throws TimeoutException, GatewayException, IOException, InterruptedException
{
// TODO: (TD) Implement Text Mode.
return false;
}
private void readMessagesTEXT(List msgList, MessageClasses msgClass, int limit) throws TimeoutException, GatewayException, IOException, InterruptedException
{
int i, j, memIndex;
byte[] bytes;
String response, line, msgText, originator, dateStr, refNo;
BufferedReader reader;
StringTokenizer tokens;
InboundMessage msg;
Calendar cal1 = Calendar.getInstance();
Calendar cal2 = Calendar.getInstance();
if (limit < 0) limit = 0;
for (int ml = 0; ml < (atHandler.storageLocations.length() / 2); ml++)
{
if (atHandler.setStorageLocation(atHandler.storageLocations.substring((ml * 2), (ml * 2) + 2)))
{
response = atHandler.listMessages(msgClass);
response = response.replaceAll("\\s+OK\\s+", "\nOK");
reader = new BufferedReader(new StringReader(response));
for (;;)
{
line = reader.readLine().trim();
if (line == null) break;
line = line.trim();
if (line.length() > 0) break;
}
while (true)
{
if (line == null) break;
line = line.trim();
if (line.length() <= 0 || line.equalsIgnoreCase("OK")) break;
i = line.indexOf(':');
j = line.indexOf(',');
memIndex = Integer.parseInt(line.substring(i + 1, j).trim());
tokens = new StringTokenizer(line, ",");
tokens.nextToken();
tokens.nextToken();
if (Character.isDigit(tokens.nextToken().trim().charAt(0)))
{
line = line.replaceAll(",,", ", ,");
tokens = new StringTokenizer(line, ",");
tokens.nextToken();
tokens.nextToken();
tokens.nextToken();
refNo = tokens.nextToken();
tokens.nextToken();
dateStr = tokens.nextToken().replaceAll("\"", "");
cal1.set(Calendar.YEAR, 2000 + Integer.parseInt(dateStr.substring(0, 2)));
cal1.set(Calendar.MONTH, Integer.parseInt(dateStr.substring(3, 5)) - 1);
cal1.set(Calendar.DAY_OF_MONTH, Integer.parseInt(dateStr.substring(6, 8)));
dateStr = tokens.nextToken().replaceAll("\"", "");
cal1.set(Calendar.HOUR_OF_DAY, Integer.parseInt(dateStr.substring(0, 2)));
cal1.set(Calendar.MINUTE, Integer.parseInt(dateStr.substring(3, 5)));
cal1.set(Calendar.SECOND, Integer.parseInt(dateStr.substring(6, 8)));
dateStr = tokens.nextToken().replaceAll("\"", "");
cal2.set(Calendar.YEAR, 2000 + Integer.parseInt(dateStr.substring(0, 2)));
cal2.set(Calendar.MONTH, Integer.parseInt(dateStr.substring(3, 5)) - 1);
cal2.set(Calendar.DAY_OF_MONTH, Integer.parseInt(dateStr.substring(6, 8)));
dateStr = tokens.nextToken().replaceAll("\"", "");
cal2.set(Calendar.HOUR_OF_DAY, Integer.parseInt(dateStr.substring(0, 2)));
cal2.set(Calendar.MINUTE, Integer.parseInt(dateStr.substring(3, 5)));
cal2.set(Calendar.SECOND, Integer.parseInt(dateStr.substring(6, 8)));
msg = new StatusReportMessage(refNo, memIndex, atHandler.storageLocations.substring((ml * 2), (ml * 2) + 2), cal1.getTime(), cal2.getTime());
msg.setGatewayId(gtwId);
logger.debug("IN-DTLS: MI:" + msg.getMemIndex());
msgList.add(msg);
statistics.inbound++;
}
else
{
line = line.replaceAll(",,", ", ,");
tokens = new StringTokenizer(line, ",");
tokens.nextToken();
tokens.nextToken();
originator = tokens.nextToken().replaceAll("\"", "");
tokens.nextToken();
dateStr = tokens.nextToken().replaceAll("\"", "");
cal1.set(Calendar.YEAR, 2000 + Integer.parseInt(dateStr.substring(0, 2)));
cal1.set(Calendar.MONTH, Integer.parseInt(dateStr.substring(3, 5)) - 1);
cal1.set(Calendar.DAY_OF_MONTH, Integer.parseInt(dateStr.substring(6, 8)));
dateStr = tokens.nextToken().replaceAll("\"", "");
cal1.set(Calendar.HOUR_OF_DAY, Integer.parseInt(dateStr.substring(0, 2)));
cal1.set(Calendar.MINUTE, Integer.parseInt(dateStr.substring(3, 5)));
cal1.set(Calendar.SECOND, Integer.parseInt(dateStr.substring(6, 8)));
msgText = reader.readLine().trim();
bytes = new byte[msgText.length() / 2];
j = 0;
for (i = 0; i < msgText.length(); i += 2)
{
bytes[j] = Byte.parseByte(msgText.substring(i, i + 2), 16);
j++;
}
msgText = GSMAlphabet.bytesToString(bytes);
msg = new InboundMessage(cal1.getTime(), originator, msgText, memIndex, atHandler.storageLocations.substring((ml * 2), (ml * 2) + 2));
msg.setGatewayId(gtwId);
logger.debug("IN-DTLS: MI:" + msg.getMemIndex());
msgList.add(msg);
statistics.inbound++;
}
line = reader.readLine().trim();
while (line.length() == 0)
line = reader.readLine().trim();
}
reader.close();
}
}
}
private void readMessagesPDU(List msgList, MessageClasses messageClass, int limit) throws TimeoutException, GatewayException, IOException, InterruptedException
{
int i, j, memIndex;
String response, line, pdu;
BufferedReader reader;
InboundMessage mpMsg;
if (limit < 0) limit = 0;
mpMsg = null;
for (int ml = 0; ml < (atHandler.storageLocations.length() / 2); ml++)
{
if (atHandler.setStorageLocation(atHandler.storageLocations.substring((ml * 2), (ml * 2) + 2)))
{
response = atHandler.listMessages(messageClass);
response = response.replaceAll("\\s+OK\\s+", "\nOK");
reader = new BufferedReader(new StringReader(response));
for (;;)
{
line = reader.readLine().trim();
if (line == null) break;
line = line.trim();
if (line.length() > 0) break;
}
while (true)
{
if (line == null) break;
line = line.trim();
if (line.length() <= 0 || line.equalsIgnoreCase("OK")) break;
i = line.indexOf(':');
j = line.indexOf(',');
memIndex = Integer.parseInt(line.substring(i + 1, j).trim());
pdu = reader.readLine().trim();
try
{
if (isInboundMessage(pdu))
{
InboundMessage msg;
msg = new InboundMessage(pdu, memIndex, atHandler.storageLocations.substring((ml * 2), (ml * 2) + 2));
msg.setGatewayId(gtwId);
logger.debug("IN-DTLS: MI:" + msg.getMemIndex() + " REF:" + msg.getMpRefNo() + " MAX:" + msg.getMpMaxNo() + " SEQ:" + msg.getMpSeqNo());
if (msg.getMpRefNo() == 0)
{
if (mpMsg != null) mpMsg = null;
msgList.add(msg);
statistics.inbound++;
}
else
{
int k, l;
List tmpList;
InboundMessage listMsg;
boolean found, duplicate;
found = false;
for (k = 0; k < mpMsgList.size(); k++)
{
tmpList = (List) mpMsgList.get(k);
listMsg = (InboundMessage) tmpList.get(0);
if (listMsg.getMpRefNo() == msg.getMpRefNo())
{
duplicate = false;
for (l = 0; l < tmpList.size(); l++)
{
listMsg = (InboundMessage) tmpList.get(l);
if (listMsg.getMpSeqNo() == msg.getMpSeqNo())
{
duplicate = true;
break;
}
}
if (!duplicate) tmpList.add(msg);
found = true;
break;
}
}
if (!found)
{
tmpList = new ArrayList();
tmpList.add(msg);
mpMsgList.add(tmpList);
}
}
}
else if (isStatusReportMessage(pdu))
{
StatusReportMessage msg;
msg = new StatusReportMessage(pdu, memIndex, atHandler.storageLocations.substring((ml * 2), (ml * 2) + 2));
msg.setGatewayId(gtwId);
msgList.add(msg);
statistics.inbound++;
}
}
catch (Exception e)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -