package sms.gateway;
import java.io.*;
import java.util.*;
import java.sql.Timestamp;
import smpp.*;
import smpp.pdu.*;
import sms.util.*;
import sms.common.*;
import sms.database.*;
import sms.gateway.process.*;
import sms.gateway.logger.*;
import sms.gateway.buffer.SMPPACKWaitingTable;
/**
* Class <code>Gateway</code> shows how to use the SMPP toolkit.
* You can bound and unbind from the SMSC, you can send every possible
* pdu and wait for a pdu sent from the SMSC.
*/
public class Gateway extends Thread {
private static Logger logger = new Logger("Gateway");
static {
System.out.println("*************************************************");
System.out.println("* Copyright (c) 2006-2007 by Phan Van Can *");
System.out.println("* SMS Gateway, version 4.0 *");
System.out.println("*************************************************");
}
//========================================================================//
// This is the SMPP session used for communication with SMSC.
private static Session session = null; //for ASYNC mode and transmit in SYNC mode
private static Session sessionr = null; //for receive in SYNC mode
public static Session getSession() { return session; }
public static Session getSessionR() { return sessionr; }
public static void setSession(Session newSession) {
session = newSession;
if (session != null) setBound(true);
else setBound(false);
}
public static void setSessionR(Session newSessionR) {
sessionr = newSessionR;
if (sessionr != null) setBoundR(true);
else setBoundR(false);
}
// If the application is bound to the SMSC.
private static boolean bound = false;
private static boolean boundr = false;
private static boolean running = true; //gateway is running
public static boolean isBound() { return bound; }
public static boolean isBoundR() { return boundr; }
public static boolean isRunning() { return running; }
public static void setBound(boolean value) { bound = value; }
public static void setBoundR(boolean value) { boundr = value; }
public static void setRunning(boolean value) { running = value; }
//========================================================================//
//queue contains data (SubmitSM, DeliverRespSM) sending to SMSC
private static Queue toSMSCQueue = null;
//queues contain PDUs from SMSC
private static Queue requestQueue = null;
private static Queue responseQueue = null;
private static Queue deliveryQueue = null;
//Log queues
private static Queue moQueue = null;
private static Queue moLogQueue = null;
private static Queue mtLogQueue = null;
//CDR Queue
private static Queue cdrQueue = null;
//Init queue
static {
toSMSCQueue = new SMPPQueue("submit");
requestQueue = new SMPPQueue("deliver");
responseQueue = new SMPPQueue("submit_resp");
deliveryQueue = new SMPPQueue("report");
moLogQueue = new MOQueue("mo_log");
moQueue = new MOQueue("mo_queue");
mtLogQueue = new Queue("mt_log");
cdrQueue = new Queue("cdr_pdu");
}
public static Queue getToSMSCQueue() { return toSMSCQueue; }
public static Queue getRequestQueue() { return requestQueue; }
public static Queue getResponseQueue() { return responseQueue; }
public static Queue getDeliveryQueue() { return deliveryQueue; }
public static Queue getMOLogQueue() { return moLogQueue; }
public static Queue getMOQueue() { return moQueue; }
public static Queue getMTLogQueue() { return mtLogQueue; }
public static Queue getCDRQueue() { return cdrQueue; }
//========================================================================//
private SMPPEventListener pduListener = null;
public SMPPEventListener getPDUEventListener() {
return pduListener;
}
//========================================================================//
private static Map reportWaitingTable = new Hashtable();
public static Map getReportWaitingTable() {
return reportWaitingTable;
}
private static Vector liveThreads = new Vector();
static Vector getLiveThreads() {
return liveThreads;
}
public static void addLiveThread(Thread thread) {
synchronized (liveThreads) {
liveThreads.add(thread);
}
}
public static boolean removeThread(Thread diedThread) {
synchronized (liveThreads) {
Iterator it = liveThreads.iterator();
while (it.hasNext()) {
Thread currThread = (Thread) it.next();
if (currThread.equals(diedThread)) {
liveThreads.remove(diedThread);
return true;
}
}
return false;
}
}
//========================================================================//
public static void main(String args[]) {
Gateway gateway = new Gateway();
try {
LoggerConfig.loadProperties();
} catch (IOException e) {
logger.error("Khong tim thay file cau hinh: " + e.getMessage());
}
try {
GatewayConfig.loadProperties();
} catch (IOException e) {
logger.error("Khong tim thay file cau hinh: " + e.getMessage());
}
try {
DBConfig.loadProperties();
} catch (IOException e) {
logger.error("Khong tim thay file cau hinh: " + e.getMessage());
}
if (LoggerConfig.LOG_TO_CONSOLE == 1) {
new KeyboardReader().start();
}
//Load and init DBPool, Logger
//THO, 16/05/2006 disabled to test
sms.database.DBPool.load();
//Load file into SMPPWaitingTable
SMPPACKWaitingTable.load();
gateway.bind(); //blocked until bound to SMSC
gateway.start();
}
public void run() {
new MOLogger().start();
new MTLogger().start();
new ResponseProcessor().start();
new CDRQueuer().start(); //log to CDR_QUEUE
new MOQueuer().start();
new SMPPSender().start();
new RequestProcessor().start();
new SMPPACKWaitingChecker().start();
switch(GatewayConfig.bindMode) {
case Constants.BIND_MODE_TRX:
new EMSBuilder().start();
if (GatewayConfig.reportRequired) {
new ReportProcessor().start();
}
break;
case Constants.BIND_MODE_TX:
new EMSBuilder().start();
if (GatewayConfig.reportRequired) {
new ReportProcessor().start();
}
if (!GatewayConfig.asynchronous) {
new SMPPReceiver().start();
}
break;
case Constants.BIND_MODE_RX:
if (!GatewayConfig.asynchronous) {
new SMPPReceiver().start();
}
break;
default:
System.exit(1);
}
//All cases
new EnquireLinkThread().start();
logger.log2C("Gateway started.");
}
synchronized public static void bind() {
if (bound) { //connected (Open) and bound to SMSC
logger.info("Already bound, unbind first.");
return;
}
//Here, gateway is unbound to SMSC
if (GatewayConfig.asynchronous) {
setSession(SMPPTool.bindASync(GatewayConfig.bindMode));
} else {
if (GatewayConfig.bindMode == Constants.BIND_MODE_TX) {
setSession(SMPPTool.bindSyncTransmitter());
} else if (GatewayConfig.bindMode == Constants.BIND_MODE_RX) {
setSessionR(SMPPTool.bindSyncReceiver());
} else if (GatewayConfig.bindMode == Constants.BIND_MODE_TRX) {
setSession(SMPPTool.bindSyncTransmitter());
setSessionR(SMPPTool.bindSyncReceiver());
} else {
setSession(SMPPTool.bindSyncTransmitter());
setSessionR(SMPPTool.bindSyncReceiver());
}
}
}
/**
* Ubinds (logs out) from the SMSC and closes the connection.
*/
synchronized public static void unbind() {
try {
if (bound || boundr)
logger.info("Going to unbind...");
if (bound) {
UnbindResp response = session.unbind();
logger.log2C("Unbind response " + response.debugString());
bound = false;
}
if (boundr) { //Bound in Receiver (& SYNC) mode
if (sessionr.getReceiver().isReceiver()) {
logger.log2C("It may take a while to stop the receiver.");
logger.log2C("Wait a moment!!!");
}
UnbindResp response = sessionr.unbind();
logger.log2C("Unbind response " + response.debugString());
boundr = false;
}
if(!bound && !boundr) {
logger.log2C("UnBound to SMSC At " + new java.sql.Timestamp(System.currentTimeMillis()) + "!!!");
logger.logConnectionStateChanged("UNBOUND to SMSC\r\n");
}
} catch (Exception ex) {
logger.error("Unbind operation failed: " + ex.getMessage());
}
}
/**
* If bound, unbinds and then exits this application.
*/
public static void exit() {
running = false;
//Save to file (temporary disable)
//Queue.storeAllQueueData();
//Save to file (temporary disable)
//SMPPACKWaitingTable.storeData();
//Unbind to SMSC
if (bound || boundr) {
unbind();
}
// Close all db connections in the pool.
DBPool.release();
// logger.log2C("waiting");
// int nLoop = 0;
// while (liveThreads.size() > 0 && nLoop <= 5) {
// System.out.print(".");
// try {
// sleep(500L);
// nLoop++;
// } catch (InterruptedException ex) { }
// }
System.out.println();
System.out.println("Stopped.");
System.exit(0);
}
}