📄 smppconnection.java
字号:
/* * Java SMPP API * Copyright (C) 1998 - 2001 by Oran Kelly * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * A copy of the LGPL can be viewed at http://www.gnu.org/copyleft/lesser.html * Java SMPP API author: orank@users.sf.net * Java SMPP API Homepage: http://smppapi.sourceforge.net/ */package ie.omk.smpp;import java.io.*;import java.net.*;import java.util.*;import ie.omk.smpp.message.*;import ie.omk.smpp.net.*;import ie.omk.smpp.util.*;import ie.omk.debug.Debug;/** SMPP client connection (ESME). * This is an abstract class which provides the base functionality for * SmppTransmitter and SmppReceiver. * @see ie.omk.smpp.SmppTransmitter * @see ie.omk.smpp.SmppReceiver * @author Oran Kelly * @version 1.0 */public abstract class SmppConnection extends java.util.Observable implements java.lang.Runnable{ /** Connection state: not bound to the SMSC. */ public static final int UNBOUND = 0; /** Connection state: waiting for successful acknowledgement to bind * request. */ public static final int BINDING = 1; /** Connection state: bound to the SMSC. */ public static final int BOUND = 2; /** Connection state: waiting for successful acknowledgement to unbind * request or waiting for application to respond to unbind request. */ public static final int UNBINDING = 3; /** SMPP protocol version number. This may be negotiated by the bind * operation. */ protected int interfaceVersion = 0x33; /** Packet listener thread for Asyncronous comms. */ private Thread rcvThread = null; /** Byte buffer used in readNextPacketInternal. */ private byte[] buf = new byte[300]; /** Sequence number */ private int seqNum = 1; /** Sequence numbering lock object. */ private Object seqNumLock = new Object(); /** The network link (virtual circuit) to the SMSC */ private SmscLink link = null; /** Current state of the SMPP connection. * Possible states are UNBOUND, BINDING, BOUND and UNBINDING. */ private int state = UNBOUND; /** Specify whether the listener thread will automatically ack * enquire_link primitives received from the Smsc */ protected boolean ackQryLinks = true; /** Automatically acknowledge incoming deliver_sm messages. * Only valid for the Receiver */ protected boolean ackDeliverSm = false; /** Is the user using synchronous are async communication?. */ protected boolean asyncComms = false; /** Create a new Smpp connection. * @param link The network link object to the Smsc (cannot be null) * @exception java.lang.NullPointerException If the link is null */ protected SmppConnection(SmscLink link) { if(link == null) throw new NullPointerException("Smsc Link cannot be null."); this.link = link; } /** Create a new Smpp connection specifying the type of communications * desired. * @param link The network link object to the Smsc (cannot be null) * @param async true for asyncronous communication, false for synchronous. * @exception java.lang.NullPointerException If the link is null */ protected SmppConnection(SmscLink link, boolean async) { this(link); this.asyncComms = async; createRecvThread(); } /** Create the receiver thread if asynchronous communications is on, does * nothing otherwise. */ private void createRecvThread() { if (asyncComms) { rcvThread = new Thread(this); rcvThread.setDaemon(true); } } /** Set the state of this ESME. * @see ie.omk.smpp.SmppConnection#getState */ private synchronized void setState(int state) { this.state = state; } /** Get the current state of the ESME. One of UNBOUND, BINDING, BOUND or * UNBINDING. */ public synchronized int getState() { return (this.state); } /** Method to open the link to the SMSC. * @exception java.io.IOException if an i/o error occurs. */ protected void openLink() throws java.io.IOException { if (!this.link.isConnected()) { Debug.d(this, "openLink", "Opening network link.", 1); this.link.open(); } } /** Get the interface version value as an integer. The version is encoded * as a hexadecimal integer. {@link #setInterfaceVersion(int)} describes * the current accepted values. * @see #setInterfaceVersion(int) */ public int getInterfaceVersion() { return (this.interfaceVersion); } /** Set the desired interface version for this connection. The default * version is 3.3 (XXX soon to be 3.4). The bind operation may negotiate * an eariler version of the protocol if the SC does not understand the * version sent by the ESME. This API will not support any version eariler * than SMPP v3.3. The interface version is encoded as follows: * <table border="1" cellspacing="1" cellpadding="1"> * <tr><th>SMPP version</th><th>Version value</th></tr> * <tr><td>v3.4</td><td>0x34</td></tr> * <tr><td>v3.3</td><td>0x33</td></tr> * <tr> * <td colspan="2" align="center"><i>All other values reserved.</i></td> * </tr> * </table> * @exception UnsupportedSMPPVersionException if <code>version</code> is * unsupported by this implementation. */ public void setInterfaceVersion(int version) throws ie.omk.smpp.UnsupportedSMPPVersionException { if (version != 0x33 || version != 0x34) throw new UnsupportedSMPPVersionException(version); else this.interfaceVersion = version; } /** Set the behaviour of automatically acking QRYLINK's from the SMSC. * By default, the listener thread will automatically ack an enquire_link * message from the Smsc so as not to lose the connection. This * can be turned off with this method. * @param true to activate automatic acknowledgment, false to disable */ public void autoAckLink(boolean b) { this.ackQryLinks = b; } /** Set the behaviour of automatically acking Deliver_Sm's from the Smsc. * By default the listener thread will <b>not</b> acknowledge a message. * @param true to activate this function, false to deactivate. */ public void autoAckMessages(boolean b) { this.ackDeliverSm = b; } /** Check is this connection automatically acking Enquire link requests. */ public boolean isAckingLinks() { return (ackQryLinks); } /** Check is this connection automatically acking delivered messages */ public boolean isAckingMessages() { return (ackDeliverSm); } /** Send an smpp request to the SMSC. * No fields in the SMPPRequest packet will be altered except for the * sequence number. The sequence number of the packet will be set by this * method according to the numbering maintained by this SmppConnection * object. The numbering policy is to start at 1 and increment by 1 for * each packet sent. * @param r The request packet to send to the SMSC * @return The response packet returned by the SMSC, or null if * asynchronous communication is being used. * @exception java.io.IOException If a network error occurs */ public SMPPResponse sendRequest(SMPPRequest r) throws java.io.IOException, ie.omk.smpp.SMPPException { if (link == null) throw new IOException("Connection to the SMSC is not open."); SMPPPacket resp = null; r.setSequenceNum(nextPacket()); // Special packet handling.. int id = r.getCommandId(); if (id == SMPPPacket.ESME_BNDTRN || id == SMPPPacket.ESME_BNDRCV) { if (this.state != UNBOUND) throw new AlreadyBoundException(); openLink(); setState(BINDING); if (asyncComms) { if (rcvThread == null) createRecvThread(); if (!rcvThread.isAlive()) rcvThread.start(); } } id = -1; link.write(r); Debug.send(r); if (!asyncComms) { resp = readNextPacketInternal(); id = resp.getCommandId(); Debug.recv(resp); if(!(resp instanceof SMPPResponse)) { Debug.d(this, "sendRequest", "packet received from " + "SMSC is not an SMPPResponse!", 1); } } // Special! if (id == SMPPPacket.ESME_BNDTRN_RESP || id == SMPPPacket.ESME_BNDRCV_RESP) { if (resp.getCommandStatus() == 0) setState(BOUND); } return ((SMPPResponse)resp); } /** Send an smpp response packet to the SMSC * @param r The response packet to send to the SMSC * @exception ie.omk.smpp.NoSuchRequestException if the response contains a * sequence number of a request this connection has not seen. * @exception java.io.IOException If a network error occurs */ public void sendResponse(SMPPResponse resp) throws java.io.IOException, ie.omk.smpp.SMPPException { Integer key = null; if (link == null) throw new IOException("Connection to SMSC is not valid."); link.write(resp); Debug.send(resp); if (resp.getCommandId() == SMPPPacket.ESME_UBD_RESP && resp.getCommandStatus() == 0) setState(UNBOUND); } /** bind this connection to the SMSC. * Sub classes of SmppConnection must provide an implementation of this. * @param systemID The system ID of this ESME. * @param password The password used to authenticate to the SMSC. * @param systemType The system type of this ESME. * @param sourceRange The source routing information. If null, the defaults * at the SMSC will be used. * @return The bind transmitter or bind receiver response or null if * asynchronous communications is in use. * @exception java.io.IOException If a communications error occurs * @exception ie.omk.smpp.SMPPException XXX when? * @see ie.omk.smpp.SmppTransmitter#bind * @see ie.omk.smpp.SmppReceiver#bind */ public abstract SMPPResponse bind(String systemID, String password, String systemType, SmeAddress sourceRange) throws java.io.IOException, ie.omk.smpp.SMPPException; /** Unbind from the SMSC. This method constructs and sends an unbind request * packet to the SMSC. * @return The Unbind response packet, or null if asynchronous * communication is being used. * @exception ie.omk.smpp.NotBoundException if the connection is not yet * bound. * @exception java.io.IOException If a network error occurs. * @see ie.omk.smpp.SmppTransmitter#bind * @see ie.omk.smpp.SmppReceiver#bind */ public UnbindResp unbind() throws java.io.IOException, ie.omk.smpp.SMPPException { if((state != BOUND) || !(link.isConnected()))
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -