📄 smppconnection.java
字号:
throw new NotBoundException(); /* If this is set, the run() method will return when an * unbind response packet arrives, stopping the listener * thread. (after all observers have been notified of the packet) */ setState(UNBINDING); Unbind u = new Unbind(); SMPPResponse resp = sendRequest(u); if (!asyncComms) { if (resp.getCommandId() == SMPPPacket.ESME_UBD_RESP && resp.getCommandStatus() == 0) setState(UNBOUND); } return ((UnbindResp)resp); } /** Unbind from the SMSC. This method can be used to acknowledge an unbind * request from the SMSC. * @exception ie.omk.smpp.NotBoundException if the link is currently not * connected. * @exception ie.omk.smpp.AlreadyBoundException if no unbind request has * been received from the SMSC. * @exception java.io.IOException If a network error occurs. * @see ie.omk.smpp.SmppTransmitter#bind * @see ie.omk.smpp.SmppReceiver#bind */ public void unbind(UnbindResp ubr) throws java.io.IOException, ie.omk.smpp.SMPPException { if (state != UNBINDING) throw new NotBoundException("Link is not connected."); if (!(link.isConnected())) throw new AlreadyBoundException("No unbind request received."); sendResponse(ubr); } /** Use of this <b><i>highly</i></b> discouraged. * This is in case of emergency and stuff. * Closing the connection to the Smsc without unbinding * first can cause horrific trouble with runaway processes. Don't * do it! */ public void force_unbind() throws ie.omk.smpp.SMPPException { if(state != UNBINDING) { Debug.warn(this, "force_close", "Force tried before normal unbind."); throw new AlreadyBoundException("Try a normal unbind first."); } Debug.d(this, "force_unbind", "Attempting to force the connection shut.", 4); try { // The thread must DIE!!!! if(rcvThread != null && rcvThread.isAlive()) { setState(UNBOUND); try { Thread.sleep(1000); } catch (InterruptedException x) { } if (rcvThread.isAlive()) Debug.warn(this, "force_unbind", "ERROR! Listener thread has not died."); } link.close(); } catch(IOException ix) { } return; } /** Acknowledge an EnquireLink received from the Smsc * @exception java.io.IOException If a communications error occurs. * @exception ie.omk.smpp.SMPPExceptione XXX when? */ public void ackEnquireLink(EnquireLink rq) throws java.io.IOException, ie.omk.smpp.SMPPException { EnquireLinkResp resp = new EnquireLinkResp(rq); sendResponse(resp); Debug.d(this, "ackEnquireLink", "responding..", 3); } /** Do a confidence check on the SMPP link to the SMSC. * @return The Enquire link response packet or null if asynchronous * communication is in use. * @exception java.io.IOException If a network error occurs * @exception ie.omk.smpp.SMPPExceptione XXX when? */ public EnquireLinkResp enquireLink() throws java.io.IOException, ie.omk.smpp.SMPPException { EnquireLink s = new EnquireLink(); SMPPResponse resp = sendRequest(s); Debug.d(this, "enquireLink", "sent enquire_link", 3); if (resp != null) Debug.d(this, "enquireLink", "response received", 3); return ((EnquireLinkResp)resp); } /** Report whether the connection is bound or not. * @return true if the connection is bound */ public boolean isBound() { return (state == BOUND); } /** Reset's this connection as if before binding. * This loses all packets currently stored and reset's the * sequence numbering to the start. * @exception ie.omk.smpp.AlreadyBoundException if the connection is * currently bound to the SMSC. */ public void reset() throws ie.omk.smpp.SMPPException { if(state == BOUND) { Debug.warn(this, "reset", "Attempt to reset a bound connection."); throw new AlreadyBoundException("Cannot reset connection " + "while bound"); } synchronized (seqNumLock) { seqNum = 1; } Debug.d(this, "reset", "SmppConnection reset", 1); } /** Get the next sequence number for the next SMPP packet. * @return The next valid sequence number for this connection. */ private int nextPacket() { synchronized (seqNumLock) { if (seqNum == 0x7fffffff) seqNum = 1; return (seqNum++); } } /** Get the current packet sequence number. * This method will not affect the current value of the sequence * number, just allow applications read what the current value is. */ public int getSeqNum() { return (seqNum); } /** Read in the next packet from the SMSC link. * If asynchronous communications is in use, calling this method results in * an SMPPException as the listener thread will be hogging the input stream * of the socket connection. * @return The next SMPP packet from the SMSC. * @exception java.io.IOException If an I/O error occurs. * @exception ie.omk.smpp.SMPPException If asynchronous comms is in use. */ public SMPPPacket readNextPacket() throws java.io.IOException, ie.omk.smpp.SMPPException { if (asyncComms) throw new InvalidOperationException("Asynchronous comms in use."); else return (readNextPacketInternal()); } /** Read the next packet from the SMSC link. Internal version...handles * special case packets like bind responses and unbind request and * responses. * @return The read SMPP packet, or null if the connection timed out. */ private SMPPPacket readNextPacketInternal() throws java.io.IOException, ie.omk.smpp.SMPPException { SMPPPacket pak = null; int st = -1; this.buf = link.read(this.buf); pak = PacketFactory.newPacket(this.buf); if (pak != null) { Debug.d(this, "readNextPacketInternal", "Packet received: " + pak.getCommandId(), 6); // Special case handling for certain packet types.. st = pak.getCommandStatus(); switch (pak.getCommandId()) { case SMPPPacket.ESME_BNDTRN_RESP: case SMPPPacket.ESME_BNDRCV_RESP: if (state == BINDING && st == 0) setState(BOUND); break; case SMPPPacket.ESME_UBD_RESP: if (state == UNBINDING && st == 0) { Debug.d(this, "readNextPacketInternal", "Successfully unbound.", 3); setState(UNBOUND); } break; case SMPPPacket.ESME_UBD: Debug.d(this, "readNextPacketInternal", "SMSC requested unbind.", 2); setState(UNBINDING); break; } } return (pak); } /** Add an observer to receive SmppEvents from this connection. * If asynchronous communication is not turned on, this method call has no * effect. */ public void addObserver(Observer ob) { if (asyncComms) super.addObserver(ob); } /** Notify all observers that a new packet has arrived. * @param b The packet that just arrived. */ public void notifyObservers(Object b) { if(! (b instanceof SMPPPacket)) { throw new IllegalArgumentException("Notify Observers needs an " + "SMPPPacket class."); } // Create a new SmppEvent and notify observers of it.... Object details = SmppEvent.detailFactory((SMPPPacket)b); SmppEvent ev = new SmppEvent(this, (SMPPPacket)b, details); this.setChanged(); super.notifyObservers(ev); } /** Listener thread method for asynchronous communication. */ public void run() { SMPPPacket pak = null; int smppEx = 0, id = 0, st = 0; Debug.d(this, "run", "Listener thread started", 4); try { while (state != UNBOUND) { try { pak = readNextPacketInternal(); if (pak == null) { // XXX Send an event to the application?? continue; } } catch (SMPPException x) { smppEx++; if (smppEx > 3) { Debug.d(this, "run", "3 SMPP exceptions in receiver" + " thread. Terminating.", 2); // XXX send an event to the application and stop the // thread. throw x; } } id = pak.getCommandId(); st = pak.getCommandStatus(); // Handle special case packets.. switch (id) { case SMPPPacket.SMSC_DELIVER_SM: if (ackDeliverSm) ackDelivery((DeliverSM)pak); break; case SMPPPacket.ESME_QRYLINK: if (ackQryLinks) ackLinkQuery((EnquireLink)pak); break; } // Tell all the observers about the new packet Debug.d(this, "run", "Notifying observers..", 4); notifyObservers(pak); } } catch (IOException x) { // This is fatal to the receiver thread. Debug.d(this, "run", "IOException: " + x.getMessage(), 2); setState(UNBOUND); SmppConnectionDropPacket p = new SmppConnectionDropPacket(0xffffffff); p.setErrorMessage(x.getMessage()); notifyObservers(p); } catch (Exception x) { x.printStackTrace(System.err); // XXX handle? } finally { // make sure other code doesn't try to restart the rcvThread.. rcvThread = null; } } private void ackDelivery(DeliverSM dm) { try { Debug.d(this, "ackDelivery", "Auto acking deliver_sm " + dm.getSequenceNum(), 4); DeliverSMResp dmr = new DeliverSMResp(dm); sendResponse(dmr); } catch (SMPPException x) { Debug.d(this, "ackDelivery", "SMPP exception acking deliver_sm " + dm.getSequenceNum(), 3); } catch (IOException x) { Debug.d(this, "ackDelivery", "IO exception acking deliver_sm " + dm.getSequenceNum(), 3); } } private void ackLinkQuery(EnquireLink el) { try { Debug.d(this, "ackLinkEnquire", "Auto acking enquire_link " + el.getSequenceNum(), 4); EnquireLinkResp elr = new EnquireLinkResp(el); sendResponse(elr); } catch (SMPPException x) { Debug.d(this, "ackLinkEnquire", "SMPP exception acking " + "enquire_link " + el.getSequenceNum(), 3); } catch (IOException x) { Debug.d(this, "ackLinkEnquire", "IO exception acking enquire_link " + el.getSequenceNum(), 3); } }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -