📄 connection.java
字号:
/** * Method to open the link to the SMSC. This method will connect the * underlying SmscLink object if necessary and reset the sequence numbering * scheme to the beginning. * * @throws java.io.IOException * if an i/o error occurs while opening the connection. */ protected void openLink() throws java.io.IOException { if (!this.link.isConnected()) { LOGGER.info("Opening network link."); this.link.open(); if (this.seqNumScheme != null) { this.seqNumScheme.reset(); } } else { LOGGER.debug("openLink called, link already open"); } } /** * Close the underlying network link to the SMSC. This method calls the * underlying link's <code>close</code> method to actually shutdown the * network connection to the SMSC. * * @throws ie.omk.smpp.IllegalStateException * if an attempt is made to close the connection while bound to * the SMSC. * @throws java.io.IOException * if an I/O exception occurs while trying to close the link. * @see ie.omk.smpp.net.SmscLink#close */ public void closeLink() throws IOException { if (getState() != UNBOUND) { throw new IllegalStateException( "Cannot close the link while bound to the SMSC"); } if (this.link.isConnected()) { LOGGER.info("Shutting down the network link"); this.link.close(); } else { LOGGER.debug("closeLink called on an unopen connection"); } } /** * Get the interface version. * * @see #setInterfaceVersion(SMPPVersion) */ public SMPPVersion getInterfaceVersion() { return this.interfaceVersion; } /** * Set the desired interface version for this connection. The default * version is 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> */ public void setInterfaceVersion(SMPPVersion interfaceVersion) { LOGGER.info("setInterfaceVersion " + interfaceVersion); this.interfaceVersion = interfaceVersion; this.supportOptionalParams = interfaceVersion.isSupportOptionalParams(); } /** * Set the behaviour of automatically acking ENQUIRE_LINK's from the SMSC * (only valid in <b>asynchronous </b> mode). 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 b * 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 * (only valid in <b>asynchronous </b> mode). By default the listener thread * will <b>not </b> acknowledge a message. Applications which are using the * synchronous mode of communication will always have to handle enquire link * requests themselves. * * @param b * 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 in * asynchronous mode. */ public boolean isAckingLinks() { return ackQryLinks; } /** * Check is this connection automatically acking delivered messages */ public boolean isAckingMessages() { return ackDeliverSm; } /** * Acknowledge a DeliverSM command received from the Smsc. * * @param rq * The deliver_sm request to respond to. * @throws java.io.IOException * If an I/O error occurs writing the response packet to the * network connection. */ public void ackDeliverSm(DeliverSM rq) throws java.io.IOException { DeliverSMResp rsp = new DeliverSMResp(rq); sendResponse(rsp); LOGGER.info("deliver_sm_resp sent."); } /** * Send an smpp request to the SMSC. No fields in the SMPPRequest packet * will be altered except possibly the sequence number. The sequence number * will be assigned the next number as defined by this Connection's sequence * numbering scheme. If the sequence numbering scheme class is * <code>null</code> for this Connection, no number will be assigned. By * default, the {@link ie.omk.smpp.util.DefaultSequenceScheme}class is used * to assign sequence numbers to packets. <br /> * <b>IMPORTANT </b>: You <i>must </i> use the <code>bind</code> and * <code>unbind</code> methods to carry out those operations. Attempting * to send an bind or unbind packet using this method will result in an * <code>UnsupportedOperationException</code> being thrown. * * @param request * The request packet to send to the SMSC * @return The response packet returned by the SMSC, or null if asynchronous * communication is being used. * @throws java.lang.NullPointerException * if <code>r</code> is null. * @throws java.net.SocketTimeoutException * If a socket timeout occurs while waiting for a response * packet. (Only in synchronized mode). * @throws java.io.IOException * If an I/O error occurs while writing the request packet to * the network connection. * @throws ie.omk.smpp.UnsupportedOperationException * If this connection type does not support operation * <code>r</code>. For example, a receiver link does not * support the submit_sm operation. * @throws ie.omk.smpp.AlreadyBoundException * If the request type is a bind packet and this connection is * already bound. * @throws ie.omk.smpp.message.SMPPProtocolException * If synchronous communications is in use and the incoming * response packet violates the SMPP specification, this * exception will be thrown. * @see #setSeqNumScheme */ public SMPPResponse sendRequest(SMPPRequest request) throws java.net.SocketTimeoutException, java.io.IOException, AlreadyBoundException, VersionException, SMPPProtocolException, UnsupportedOperationException { int id = request.getCommandId(); if (this.state != BOUND) { throw new NotBoundException("Must be bound to the SMSC before " + "sending packets"); } // Force applications to use bind and unbind if (id == SMPPPacket.BIND_RECEIVER || id == SMPPPacket.BIND_TRANSCEIVER || id == SMPPPacket.BIND_TRANSMITTER || id == SMPPPacket.UNBIND) { throw new UnsupportedOperationException( "You must use the bind and unbind methods to send those requests"); } // Very few request types allowed by a receiver connection. if (connectionType == RECEIVER) { if (id != SMPPPacket.ENQUIRE_LINK) { throw new UnsupportedOperationException( "Operation not permitted over receiver connection"); } } return sendRequestInternal(request); } /** * Send a request to the SMSC. * @throws ie.omk.smpp.version.VersionException * if the version in use does not support the request being * sent. */ protected SMPPResponse sendRequestInternal(SMPPRequest r) throws java.net.SocketTimeoutException, java.io.IOException, AlreadyBoundException, VersionException, SMPPProtocolException { SMPPResponse resp = null; if (link == null) { throw new IOException("No SMSC connection."); } processOutboundPacket(r); 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 { SMPPPacket resp = null; int expectedSeq = req.getSequenceNum(); while (true) { resp = readNextPacketInternal(); if (!resp.isRequest() && resp.getSequenceNum() == expectedSeq) { break; } else { LOGGER.info("Queuing unexpected sequence numbered packet."); if (LOGGER.isDebugEnabled()) { StringBuffer err = new StringBuffer("Expected:") .append(expectedSeq).append(" but got ") .append(resp.getSequenceNum()).append(" type: ") .append(resp.getCommandId()); LOGGER.debug(err.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 { 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; } processOutboundPacket(resp); } /** * Bind this connection to the SMSC. * Calling this method is the equivalent of calling<br /> * <code>bind(type, systemID, password, systemType, 0, 0, null);</code>. * @see #bind(int, String, String, String, int, int, String) */ 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> * 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. * </p> * <p> * If an SMSC does not supply the SC_INTERFACE_VERSION in its bind * response, then the Connection object will assume that the SMSC * does not support optional parameters. This behaviour is required * by the SMPP v3.4 specification. * </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) and the SMSC * will use default values for them. * </p> * * @param type * connection type to use, either {@link #TRANSMITTER}, * {@link #RECEIVER}or {@link #TRANSCEIVER}.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -