📄 connection.java
字号:
if (id == SMPPPacket.BIND_TRANSMITTER || id == SMPPPacket.BIND_RECEIVER || id == SMPPPacket.BIND_TRANSCEIVER) { if (this.state != UNBOUND) throw new AlreadyBoundException("Already bound to the SMSC"); openLink(); setState(BINDING); if (asyncComms) { if (rcvThread == null) createRecvThread(); // Set the socket timeout to the bind timeout try { long bindTimeout = APIConfig.getInstance().getLong( APIConfig.BIND_TIMEOUT, 0L); if (bindTimeout > 0L) { this.link.setTimeout(bindTimeout); if (logger.isDebugEnabled()) { logger.debug("Set bind timeout to " + bindTimeout); } } } catch (UnsupportedOperationException x) { logger .warn("Link does not support read timeouts - bind timeout will not work"); } if (!rcvThread.isAlive()) rcvThread.start(); } } else if (id == SMPPPacket.UNBIND) { if (!asyncComms && packetQueue.size() > 0) throw new IllegalStateException( "Cannot unbind while there are incoming packets " + "waiting responses"); if (this.state != BOUND) throw new IllegalStateException("Not currently bound"); setState(UNBINDING); } // XXX temporary...this should be removed once it's safe to assume that // no packet can be submitted that has been constructed outside the // confines of this connection's factory method. if (r.getSequenceNum() == 0 && seqNumScheme != null) r.setSequenceNum(seqNumScheme.nextNumber()); link.write(r, this.supportOptionalParams); if (!asyncComms) resp = waitForResponsePacket(r); return ((SMPPResponse) resp); } /** * Wait for a response packet from the SMSC. A response packet with the same * sequence number as <code>req</code> will be waited for from the SMSC. * If an unexpected packet arrives, either a response packet with a * different sequence number or a request packet, it will be queued for * later retrieval by the application via <code>readNextPacket</code>. * * @param req * the request packet to wait for a response to. * @return A response packet with the same sequence number as * <code>req</code>. * @throws java.net.SocketTimeoutException * if the read on the socket times out. * @see #readNextPacket * @see java.net.SocketTimeoutException */ protected SMPPResponse waitForResponsePacket(SMPPPacket req) throws java.net.SocketTimeoutException, java.io.IOException, SMPPProtocolException { try { int id = -1; SMPPPacket resp = null; int expectedSeq = req.getSequenceNum(); while (true) { resp = readNextPacketInternal(); id = resp.getCommandId(); if ((id & 0x80000000) != 0 && resp.getSequenceNum() == expectedSeq) { break; } else { logger.info("Queuing unexpected sequence numbered packet."); if (logger.isDebugEnabled()) { StringBuffer b = new StringBuffer("Expected:").append( Integer.toString(expectedSeq)).append( " but got ").append( Integer.toString(resp.getSequenceNum())) .append(" type: ").append( Integer.toString(resp.getCommandId())); logger.debug(b.toString()); } packetQueue.add(resp); } } return ((SMPPResponse) resp); } catch (java.net.SocketTimeoutException x) { // Must set our state and re-throw the exception.. logger.error("Received a socket timeout exception", x); throw x; } } /** * Determine if there are packets available for reading using * <code>readNextPacket</code>. This method is only valid for synchronous * communications...it will always return 0 if asynchronous mode is in use. * * @return 0 if there is no packet available for reading, 1 if there is data * available but the call to <code>readNextPacket</code> may block * or 2 if there is a full packet available. */ public int packetAvailable() { int ret = 0; if (!asyncComms) { if (packetQueue.size() > 0) ret = 2; else if (link.available() > 0) ret = 1; } return (ret); } /** * Send an smpp response packet to the SMSC * * @param resp * The response packet to send to the SMSC * @throws java.io.IOException * If an I/O error occurs while writing the response packet to * the output stream. */ public void sendResponse(SMPPResponse resp) throws java.io.IOException { Integer key = null; if (link == null) throw new IOException("Connection to SMSC is not valid."); try { link.write(resp, this.supportOptionalParams); } catch (java.net.SocketTimeoutException x) { logger.warn("Got a socket timeout exception", x); setState(UNBOUND); throw x; } if (resp.getCommandId() == SMPPPacket.UNBIND_RESP && resp.getCommandStatus() == 0) setState(UNBOUND); } /** * Bind this connection to the SMSC. An application must bind to an SMSC as * one of transmitter, receiver or transceiver. Binding as transmitter * allows general manipulation of messages at the SMSC including submitting * messages for delivery, cancelling, replacing and querying the state of * previously submitted messages. Binding as a receiver allows an * application to receive all messages previously queued for delivery to * it's address. The transceiver mode, which was added in version 3.4 of the * SMPP protocol, combines the functionality of both transmitter and * receiver into one connection type. * <p> * The connection object will negotiate the appropriate version for the * protocol link at bind time. If the SMSC returns the SC_INTERFACE_VERSION * optional parameter in its bind response packet, the * <code>Connection</code> will read it. If the version stated by the SMSC * is older than the current version setting of the <code>Connection</code> * then the <code>Connection</code>'s version will be downgraded to that * of the SMSC's. Otherwise, the current version will be left alone. An SMSC * supporting only version 3.3 of the API will never be able to return this * optional parameter (as they were only introduced in version 3.4). The * <code>Connection</code> will therefore assume the version to be 3.3 if * it does not receive the SC_INTERFACE_VERSION in the bind response packet. * If your SMSC does support a higher version but does not supply the * SC_INTERFACE_VERSION in its bind response, you will need to use * {@link #setInterfaceVersion}after the bind operation is complete. * </p> * <p> * Note that it is only necessary to supply values for * <code>type, systemID</code> and <code>password</code>. The other * arguments may be left at null (or zero, as applicable). * </p> * * @param type * connection type to use, either {@link #TRANSMITTER}, * {@link #RECEIVER}or {@link #TRANSCEIVER}. * @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) throws java.io.IOException, InvalidParameterValueException, IllegalArgumentException, AlreadyBoundException, VersionException, SMPPProtocolException { return (this.bind(type, systemID, password, systemType, 0, 0, null)); } /** * Bind this connection to the SMSC. An application must bind to an SMSC as * one of transmitter, receiver or transceiver. Binding as transmitter * allows general manipulation of messages at the SMSC including submitting * messages for delivery, cancelling, replacing and querying the state of * previously submitted messages. Binding as a receiver allows an * application to receive all messages previously queued for delivery to * it's address. The transceiver mode, which was added in version 3.4 of the * SMPP protocol, combines the functionality of both transmitter and * receiver into one connection type. * <p> * Note that it is only necessary to supply values for * <code>type, systemID</code> and <code>password</code>. The other * arguments may be left at null (or zero, as applicable). * </p> * * @param type * connection type to use, either {@link #TRANSMITTER}, * {@link #RECEIVER}or {@link #TRANSCEIVER}. * @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. * @param typeOfNum * the TON of the address to bind as. * @param numberPlan * the NPI of the address to bind as. * @param addrRange * the address range regular expression 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. * @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.message.SMPPProtocolException * If synchronous comms is in use and the incoming bind response * packet violates the SMPP specification, this exception is * thrown. */ 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; switch (type) { case TRANSMITTER: bindReq = new BindTransmitter(); break; case RECEIVER: bindReq = new BindReceiver(); break; case TRANSCEIVER: if (this.interfaceVersion.isOlder(SMPPVersion.V34)) { throw new VersionException("Cannot bind as " + "transceiver " + interfaceVersion.toString()); } bindReq = new BindTransceiver(); break; default: throw new IllegalArgumentException("No such connection type."); } this.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);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -