📄 connection.java
字号:
* @param systemID * the system ID to identify as to the SMSC. * @param password * password to use to authenticate to the SMSC. * @param systemType * the system type to bind as. * @return the bind response packet. * @throws java.lang.IllegalArgumentException * if a bad <code>type</code> value is supplied. * @throws ie.omk.smpp.VersionException * if an attempt is made to bind as transceiver while using SMPP * version 3.3. * @throws ie.omk.smpp.InvalidParameterValueException * If any of systemID, password, system type or address range * are outside allowed bounds or the TON or NPI is invalid. * @throws java.io.IOException * If an I/O error occurs while writing the bind packet to the * output stream. * @throws ie.omk.smpp.AlreadyBoundException * If the Connection is already bound. * @throws ie.omk.smpp.SMPPProtocolExcpetion * if synchronous communication is in use and the incoming * response packet violates the SMPP protocol. */ public BindResp bind(int type, String systemID, String password, String systemType, int typeOfNum, int numberPlan, String addrRange) throws java.io.IOException, InvalidParameterValueException, IllegalArgumentException, AlreadyBoundException, VersionException, SMPPProtocolException { Bind bindReq = null; try { switch (type) { case TRANSMITTER: bindReq = (Bind) newInstance(SMPPPacket.BIND_TRANSMITTER); break; case RECEIVER: bindReq = (Bind) newInstance(SMPPPacket.BIND_RECEIVER); break; case TRANSCEIVER: if (this.interfaceVersion.isOlder(SMPPVersion.V34)) { throw new VersionException( "Cannot bind as transceiver in " + interfaceVersion.toString()); } bindReq = (Bind) newInstance(SMPPPacket.BIND_TRANSCEIVER); break; default: throw new IllegalArgumentException("No such connection type."); } } catch (BadCommandIDException x) { LOGGER.error("Internal error in the smppapi. Please inform the maintainer.", x); } connectionType = type; LOGGER.info("Binding to the SMSC as type " + type); bindReq.setVersion(interfaceVersion); bindReq.setSystemId(systemID); bindReq.setPassword(password); bindReq.setSystemType(systemType); bindReq.setAddressTon(typeOfNum); bindReq.setAddressNpi(numberPlan); bindReq.setAddressRange(addrRange); return (BindResp) sendRequestInternal(bindReq); } /** * Unbind from the SMSC. This method will unbind the SMPP protocol * connection from the SMSC. No further SMPP operations will be possible * once unbound. If the calling application is using sync mode, it should be * sure there are no incoming packets awaiting a response (check using * {@link #packetAvailable}), otherwise an * <code>IllegalStateException</code> may be thrown. Note that this method * will <b>not </b> close the underlying network connection. * * @return The Unbind response packet, or null if asynchronous communication * is being used. * @throws ie.omk.smpp.NotBoundException * if the connection is not yet bound. * @throws ie.omk.smpp.message.SMPPProtocolException * If synchronous comms is in use and the incoming unbind_resp * packet violates the SMPP specification, this exception is * thrown. * @throws java.io.IOException * If an I/O error occurs while writing the unbind request or * reading the unbind response. */ public UnbindResp unbind() throws java.io.IOException, NotBoundException, SMPPProtocolException { if ((state != BOUND) || !(link.isConnected())) { throw new NotBoundException(); } try { LOGGER.info("Unbinding from the SMSC"); Unbind u = (Unbind) newInstance(SMPPPacket.UNBIND); return (UnbindResp) sendRequestInternal(u); } catch (BadCommandIDException x) { // similarly impossible! throw new SMPPRuntimeException("Internal smppapi error"); } } /** * Unbind from the SMSC. This method is used to acknowledge an unbind * request from the SMSC. * * @throws ie.omk.smpp.NotBoundException * if the connection is not currently bound. * @throws ie.omk.smpp.AlreadyBoundException * if no unbind request has been received from the SMSC. * @throws java.io.IOException * If an I/O error occurs while writing the response packet to * the network connection. */ 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); } /** * Force the SMPP connection down. Only use this method once it's full sure * that graceful unbinding and disconnection isn't going to work. This * method cleans up it's internal state, forcing the network connection * closed and terminating the receiver thread if necessary. * <p> * If you end up having to use this method to terminate a Connection, it is * advisable not to attempt to reuse the connection at all. Create a new * object and start from scratch. Use of this method indicates something * seriously wrong! * </p> */ public void force_unbind() { LOGGER.warn("Attempting to force SMPP connection down."); try { setState(UNBOUND); // Give the receiver a chance to die. Thread.yield(); // The thread must DIE!!!! if (rcvThread != null && rcvThread.isAlive()) { try { // Wait to see if the thread will terminate due to the state // becoming UNBOUND. Thread.sleep(1000); } catch (InterruptedException x) { LOGGER.debug( "Interrupted exception waiting on receiver to die", x); } if (rcvThread != null) { LOGGER.error("Listener thread has not died."); } rcvThread = null; } link.close(); } catch (Throwable t) { LOGGER.warn("Exception when trying to force unbind", t); } return; } /** * Acknowledge an EnquireLink received from the Smsc * * @throws java.io.IOException * If an I/O error occurs while writing to the network * connection. */ public void ackEnquireLink(EnquireLink rq) throws java.io.IOException { EnquireLinkResp resp = new EnquireLinkResp(rq); sendResponse(resp); LOGGER.info("enquire_link_resp sent."); } /** * 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. * @throws java.io.IOException * If an I/O error occurs while writing to the network * connection. * @throws ie.omk.smpp.message.SMPPProtocolException * If synchronous communications is in use and the incoming * enquire_link_resp packet violates the SMPP specification, * this exception is thrown. */ public EnquireLinkResp enquireLink() throws java.io.IOException, SMPPProtocolException { try { EnquireLink s = (EnquireLink) newInstance(SMPPPacket.ENQUIRE_LINK); SMPPResponse resp = sendRequest(s); LOGGER.debug("enquire_link request sent."); if (resp != null) { LOGGER.debug("enquire_link_response received."); } return (EnquireLinkResp) resp; } catch (BadCommandIDException x) { throw new SMPPRuntimeException("Internal smppapi error"); } } /** * Get the type of this SMPP connection. The connection type is one of * TRANSMITTER, RECEIVER or TRANSCEIVER. */ public int getConnectionType() { return connectionType; } /** * Report whether the connection is bound or not. * * @return true if the connection is bound. */ public boolean isBound() { return state == BOUND; } /** * Reset this connection's sequence numbering to the beginning. The * underlying SequenceNumberScheme's reset method is called to start from * that sequence's 'beginning'. * * @throws ie.omk.smpp.AlreadyBoundException * if the connection is currently bound to the SMSC. */ public void reset() throws AlreadyBoundException { if (state == BOUND) { LOGGER .warn("Attempt to reset sequence numbering on a bound connection"); throw new AlreadyBoundException( "Cannot reset connection while bound"); } if (this.seqNumScheme != null) { this.seqNumScheme.reset(); } LOGGER.info("Sequence numbering reset."); } /** * Set the sequence numbering scheme for this connection. A sequence * numbering scheme determines what sequence number each SMPP packet will * have. By default, {@link ie.omk.smpp.util.DefaultSequenceScheme}is used, * which will begin with sequence number 1 and increase the number by 1 for * each packet thereafter. * <p> * If the application sets the <code>scheme</code> to null, it is * responsible for maintaining and setting the sequence number for each SMPP * request it sends to the SMSC. * * @see ie.omk.smpp.util.SequenceNumberScheme * @see ie.omk.smpp.message.SMPPPacket#setSequenceNum */ public void setSeqNumScheme(SequenceNumberScheme scheme) { this.seqNumScheme = scheme; } /** * Get the current sequence numbering scheme object being used by this * connection. */ public SequenceNumberScheme getSeqNumScheme() { return this.seqNumScheme; } /** * 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. * @throws java.io.IOException * If an I/O error occurs while reading from the network * connection. * @throws ie.omk.smpp.InvalidOperationException * If asynchronous comms is in use. * @throws ie.omk.smpp.message.SMPPProtocolException * if the incoming data violates the SMPP protocol * specifications. */ public SMPPPacket readNextPacket() throws java.io.IOException, InvalidOperationException, SMPPProtocolException { if (asyncComms) { throw new InvalidOperationException("Asynchronous comms in use."); } else { if (packetQueue.size() > 0) { return (SMPPPacket) packetQueue.remove(0); } 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. * @throws java.io.IOException * If an I/O error occurs while reading from the network * connection. */ private SMPPPacket readNextPacketInternal() throws java.io.IOException, SMPPProtocolException { try { SMPPPacket pak = null; int id = -1; this.buf = link.read(this.buf); id = SMPPIO.bytesToInt(this.buf, 4, 4); pak = PacketFactory.newInstance(id); if (pak != null) { pak.readFrom(this.buf, 0); if (LOGGER.isDebugEnabled()) { StringBuffer b = new StringBuffer("Packet Received: "); int l = pak.getLength(); int s = pak.getCommandStatus(); int n = pak.getSequenceNum(); b.append("id:").append(Integer.toHexString(id)) .append(" len:").append(Integer.toString(l)) .append(" st:").append(Integer.toString(s)) .append(" sq:").append(Integer.toString(n)); LOGGER.debug(b.toString()); } processInboundPacket(pak); } return pak; } catch (BadCommandIDException x) { throw new SMPPProtocolException("Unrecognised command received", x); } } private void processOutboundPacket(SMPPPacket packet) throws IOException { int id = packet.getCommandId(); if (!interfaceVersion.isSupported(id)) { StringBuffer err = new StringBuffer(120) .append(interfaceVersion.toString()) .append(" does not support command ID 0x") .append(Integer.toHexString(id)); throw new VersionException(err.toString()); } switch (id) { case SMPPPacket.BIND_TRANSMITTER: case SMPPPacket.BIND_RECEIVER: case SMPPPacket.BIND_TRANSCEIVER: processOutboundBind((Bind) packet); break; case SMPPPacket.UNBIND: processOutboundUnbind((Unbind) packet); break; case SMPPPacket.UNBIND_RESP: processOutboundUnbindResp((UnbindResp) packet); break; } }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -