├── .gitignore
├── .travis.yml
├── CHANGELOG.md
├── LICENSE
├── Makefile
├── README.md
├── SSL.md
├── pom.xml
└── src
├── etc
├── SMPP_v3_4_Issue1_2.pdf
└── SMPP_v5_0.pdf
├── main
└── java
│ └── com
│ └── cloudhopper
│ └── smpp
│ ├── PduAsyncResponse.java
│ ├── SmppBindType.java
│ ├── SmppClient.java
│ ├── SmppConstants.java
│ ├── SmppServer.java
│ ├── SmppServerConfiguration.java
│ ├── SmppServerCounters.java
│ ├── SmppServerHandler.java
│ ├── SmppServerSession.java
│ ├── SmppSession.java
│ ├── SmppSessionConfiguration.java
│ ├── SmppSessionCounters.java
│ ├── SmppSessionHandler.java
│ ├── SmppSessionListener.java
│ ├── channel
│ ├── ChannelUtil.java
│ ├── SmppChannelConstants.java
│ ├── SmppClientConnector.java
│ ├── SmppServerConnector.java
│ ├── SmppSessionLogger.java
│ ├── SmppSessionPduDecoder.java
│ ├── SmppSessionThreadRenamer.java
│ └── SmppSessionWrapper.java
│ ├── impl
│ ├── DefaultPduAsyncResponse.java
│ ├── DefaultSmppClient.java
│ ├── DefaultSmppServer.java
│ ├── DefaultSmppServerCounters.java
│ ├── DefaultSmppSession.java
│ ├── DefaultSmppSessionCounters.java
│ ├── DefaultSmppSessionHandler.java
│ ├── PollableSmppSessionHandler.java
│ ├── SmppSessionChannelListener.java
│ └── UnboundSmppSession.java
│ ├── jmx
│ ├── DefaultSmppServerMXBean.java
│ └── DefaultSmppSessionMXBean.java
│ ├── pdu
│ ├── AlertNotification.java
│ ├── BaseBind.java
│ ├── BaseBindResp.java
│ ├── BaseSm.java
│ ├── BaseSmResp.java
│ ├── BindReceiver.java
│ ├── BindReceiverResp.java
│ ├── BindTransceiver.java
│ ├── BindTransceiverResp.java
│ ├── BindTransmitter.java
│ ├── BindTransmitterResp.java
│ ├── CancelSm.java
│ ├── CancelSmResp.java
│ ├── DataSm.java
│ ├── DataSmResp.java
│ ├── DeliverSm.java
│ ├── DeliverSmResp.java
│ ├── EmptyBody.java
│ ├── EmptyBodyResp.java
│ ├── EnquireLink.java
│ ├── EnquireLinkResp.java
│ ├── GenericNack.java
│ ├── PartialPdu.java
│ ├── PartialPduResp.java
│ ├── Pdu.java
│ ├── PduRequest.java
│ ├── PduResponse.java
│ ├── QuerySm.java
│ ├── QuerySmResp.java
│ ├── ReplaceSm.java
│ ├── ReplaceSmResp.java
│ ├── SubmitMulti.java
│ ├── SubmitMultiResp.java
│ ├── SubmitSm.java
│ ├── SubmitSmResp.java
│ ├── Unbind.java
│ └── UnbindResp.java
│ ├── simulator
│ ├── SmppSimulatorBindProcessor.java
│ ├── SmppSimulatorPduProcessor.java
│ ├── SmppSimulatorServer.java
│ ├── SmppSimulatorServerHandler.java
│ └── SmppSimulatorSessionHandler.java
│ ├── ssl
│ ├── AliasedX509ExtendedKeyManager.java
│ ├── CertificateValidator.java
│ ├── SslConfiguration.java
│ └── SslContextFactory.java
│ ├── tlv
│ ├── Tlv.java
│ └── TlvConvertException.java
│ ├── transcoder
│ ├── DefaultPduTranscoder.java
│ ├── DefaultPduTranscoderContext.java
│ ├── PduTranscoder.java
│ └── PduTranscoderContext.java
│ ├── type
│ ├── Address.java
│ ├── GenericNackException.java
│ ├── LoggingOptions.java
│ ├── NotEnoughDataInBufferException.java
│ ├── RecoverablePduException.java
│ ├── SmppBindException.java
│ ├── SmppChannelConnectException.java
│ ├── SmppChannelConnectTimeoutException.java
│ ├── SmppChannelException.java
│ ├── SmppConnectionConfiguration.java
│ ├── SmppInvalidArgumentException.java
│ ├── SmppProcessingException.java
│ ├── SmppTimeoutException.java
│ ├── TerminatingNullByteNotFoundException.java
│ ├── UnexpectedPduResponseException.java
│ ├── UnknownCommandIdException.java
│ ├── UnrecoverablePduException.java
│ └── UnsucessfulSME.java
│ └── util
│ ├── ChannelBufferUtil.java
│ ├── ConcurrentCommandCounter.java
│ ├── ConcurrentCommandStatusCounter.java
│ ├── DaemonExecutors.java
│ ├── DeliveryReceipt.java
│ ├── DeliveryReceiptException.java
│ ├── InvalidSequenceNumberException.java
│ ├── PduUtil.java
│ ├── SequenceNumber.java
│ ├── SmppSessionUtil.java
│ ├── SmppUtil.java
│ ├── StatisticsSample.java
│ └── TlvUtil.java
└── test
├── java
└── com
│ └── cloudhopper
│ └── smpp
│ ├── demo
│ ├── ClientMain.java
│ ├── DeliveryReceiptMain.java
│ ├── ParserMain.java
│ ├── PerformanceClientMain.java
│ ├── QueryCancelMain.java
│ ├── RebindMain.java
│ ├── ServerEchoMain.java
│ ├── ServerMain.java
│ ├── SimulatorMain.java
│ ├── SlowServerMain.java
│ ├── SslClientMain.java
│ ├── SslServerMain.java
│ └── persist
│ │ ├── Client.java
│ │ ├── ClientSmppSessionHandler.java
│ │ ├── DummySmppClientMessageService.java
│ │ ├── EnquireLinkTask.java
│ │ ├── LoggingUtil.java
│ │ ├── Main.java
│ │ ├── OutboundClient.java
│ │ ├── ReconnectionDaemon.java
│ │ ├── ReconnectionTask.java
│ │ └── SmppClientMessageService.java
│ ├── impl
│ ├── DefaultSmppServerTest.java
│ └── DefaultSmppSessionTest.java
│ ├── pdu
│ ├── BufferHelper.java
│ └── PduTest.java
│ ├── ssl
│ ├── SslContextFactoryTest.java
│ └── SslSessionTest.java
│ ├── tlv
│ └── TlvTest.java
│ ├── transcoder
│ ├── PduDecoderTest.java
│ └── PduEncoderTest.java
│ └── util
│ ├── ChannelBufferUtilTest.java
│ ├── ConcurrentCommandStatusCounterTest.java
│ ├── DeliveryReceiptTest.java
│ ├── PduUtilTest.java
│ ├── SequenceNumberTest.java
│ ├── SmppUtilTest.java
│ └── TlvUtilTest.java
└── resources
├── keystore
├── logback-test.xml
├── server.crt
├── server.key
└── stunnel.conf
/.gitignore:
--------------------------------------------------------------------------------
1 | *~
2 | target/
3 | .classpath
4 | .project
5 | .settings/
6 |
7 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: java
2 | jdk:
3 | - openjdk7
4 |
--------------------------------------------------------------------------------
/Makefile:
--------------------------------------------------------------------------------
1 |
2 | client:
3 | mvn -e test-compile exec:java -Dexec.classpathScope="test" -Dexec.mainClass="com.cloudhopper.smpp.demo.ClientMain"
4 |
5 | performance-client:
6 | mvn -e test-compile exec:java -Dexec.classpathScope="test" -Dexec.mainClass="com.cloudhopper.smpp.demo.PerformanceClientMain"
7 |
8 | ssl-client:
9 | mvn -e test-compile exec:java -Dexec.classpathScope="test" -Dexec.mainClass="com.cloudhopper.smpp.demo.SslClientMain"
10 |
11 | server:
12 | mvn -e test-compile exec:java -Dexec.classpathScope="test" -Dexec.mainClass="com.cloudhopper.smpp.demo.ServerMain"
13 |
14 | ssl-server:
15 | mvn -e test-compile exec:java -Dexec.classpathScope="test" -Dexec.mainClass="com.cloudhopper.smpp.demo.SslServerMain"
16 |
17 | slow-server:
18 | mvn -e test-compile exec:java -Dexec.classpathScope="test" -Dexec.mainClass="com.cloudhopper.smpp.demo.SlowServerMain"
19 |
20 | simulator:
21 | mvn -e test-compile exec:java -Dexec.classpathScope="test" -Dexec.mainClass="com.cloudhopper.smpp.demo.SimulatorMain"
22 |
23 | rebind:
24 | mvn -e test-compile exec:java -Dexec.classpathScope="test" -Dexec.mainClass="com.cloudhopper.smpp.demo.RebindMain"
25 |
26 | parser:
27 | mvn -e test-compile exec:java -Dexec.classpathScope="test" -Dexec.mainClass="com.cloudhopper.smpp.demo.ParserMain"
28 |
29 | dlr:
30 | mvn -e test-compile exec:java -Dexec.classpathScope="test" -Dexec.mainClass="com.cloudhopper.smpp.demo.DeliveryReceiptMain"
31 |
32 | persist-client:
33 | mvn -e test-compile exec:java -Dexec.classpathScope="test" -Dexec.mainClass="com.cloudhopper.smpp.demo.persist.Main"
34 |
35 | server-echo:
36 | mvn -e test-compile exec:java -Dexec.classpathScope="test" -Dexec.mainClass="com.cloudhopper.smpp.demo.ServerEchoMain"
37 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | > [!NOTE]
2 | > On 29 June 2023, Mobius Software LTD signed an agreement with Mavenir to assume development and support of the RestcommOne on prem products. For more details regarding open source / commercial differentiation, roadmap, licensing and other details please visit the [Mobius Website](https://www.mobius-software.com/telestaxannouncement).
3 |
4 | Cloudhopper SMPP by Fizzed (forked from Twitter)
5 | ================================================
6 |
7 | [](https://travis-ci.org/RestComm/cloudhopper-smpp)
8 |
9 | News
10 | ------------------------
11 |
12 | **Nov 2016**
13 |
14 | While Fizzed, Inc. took over from Twitter for a while, there is now an apparent lack of commits on the original repository for almost a year and PR pending reviews for more than 6 months.
15 | The project was forked here and will be updated regularly as it is being used in Restcomm SMSC
16 |
17 |
--------------------------------------------------------------------------------
/SSL.md:
--------------------------------------------------------------------------------
1 | # How to use SSL with cloudhopper-smpp
2 |
3 | The purpose of this document is to provide a summary of how to configuration SSL for ch-smpp servers and clients. The internal implementation uses Java Secure Sockets Extension (JSSE).
4 |
5 | ## Configuring a SMPP server with SSL transport
6 |
7 | ### Example:
8 |
9 | // Configure the server as you normally would:
10 | SmppServerConfiguration configuration = new SmppServerConfiguration();
11 | configuration.setPort(2776);
12 | ...
13 |
14 | // Then create a SSL configuration:
15 | SslConfiguration sslConfig = new SslConfiguration();
16 | sslConfig.setKeyStorePath("path/to/keystore");
17 | sslConfig.setKeyStorePassword("changeit");
18 | sslConfig.setKeyManagerPassword("changeit");
19 | sslConfig.setTrustStorePath("path/to/keystore");
20 | sslConfig.setTrustStorePassword("changeit");
21 | ...
22 |
23 | // And add it to the server configuration:
24 | configuration.setUseSsl(true);
25 | configuration.setSslConfiguration(sslConfig);
26 |
27 |
28 | ### Require client auth
29 |
30 | sslConfig.setNeedClientAuth(true);
31 |
32 |
33 | ## Configuring a SMPP client with SSL transport
34 |
35 | ### Example:
36 |
37 | // Configure the server as you normally would:
38 | SmppSessionConfiguration configuration = new SmppSessionConfiguration();
39 | configuration.setType(SmppBindType.TRANSCEIVER);
40 | configuration.setHost("127.0.0.1");
41 | configuration.setPort(2776);
42 | ...
43 |
44 | // Then create a SSL configuration:
45 | SslConfiguration sslConfig = new SslConfiguration();
46 | // Which trusts all certs by default. You can turn this off with
47 | // sslConfig.setTrustAll(false);
48 | ...
49 |
50 | // And add it to the server configuration:
51 | configuration.setSslConfiguration(sslConfig);
52 | configuration.setUseSsl(true);
53 |
54 | ### Validate certificates
55 |
56 | sslConfig.setValidateCerts(true);
57 | sslConfig.setValidatePeerCerts(true);
58 |
59 |
60 | ## Generating key pairs and certificates
61 |
62 | Generating Keys and Certificates with the JDK's keytool
63 |
64 | keytool -keystore keystore -alias smpp -genkey -keyalg RSA
65 |
66 | Generating Keys and Certificates with OpenSSL
67 |
68 | openssl genrsa -des3 -out smpp.key
69 | openssl req -new -x509 -key smpp.key -out smpp.crt
70 |
71 | ## Requesting a trusted certificate
72 |
73 | Generating a CSR from keytool
74 |
75 | keytool -certreq -alias smpp -keystore keystore -file smpp.csr
76 |
77 | Generating a CSR from OpenSSL
78 |
79 | openssl req -new -key smpp.key -out smpp.csr
80 |
81 | ## Loading keys and certificates
82 |
83 | Loading Certificates with keytool
84 |
85 | The following command loads a PEM encoded certificate in the smpp.crt file into a JSSE keystore:
86 |
87 | keytool -keystore keystore -import -alias smpp -file smpp.crt -trustcacerts
88 |
89 | Loading Keys and Certificates via PKCS12
90 |
91 | If you have a key and certificate in separate files, you need to combine them into a PKCS12 format file to load into a new keystore. The certificate can be one you generated yourself or one returned from a CA in response to your CSR.
92 |
93 | The following OpenSSL command combines the keys in smpp.key and the certificate in the smpp.crt file into the smpp.pkcs12 file.
94 |
95 | openssl pkcs12 -inkey smpp.key -in smpp.crt -export -out smpp.pkcs12
96 | keytool -importkeystore -srckeystore smpp.pkcs12 -srcstoretype PKCS12 -destkeystore keystore
97 |
98 |
99 | ## Appendix
100 |
101 | ### Interop with stunnel
102 |
103 | This library has been tested with stunnel4 wrapping both client and servers. There is a sample stunnel.conf in src/test/resources that works with `make server` and `make ssl-client`. The SSL implementation should be compatible with other TLS/SSL encryption wrappers, assuming the JDK you are using supports the same cryptographic algorithms as the encryption wrapper.
104 |
105 | ### Known issues
106 |
107 |
108 |
109 |
--------------------------------------------------------------------------------
/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 4.0.0
4 | org.restcomm.smpp
5 | ch-smpp
6 | jar
7 | 5.0.10-SNAPSHOT
8 | ch-smpp
9 | Efficient, scalable, and flexible Java implementation of the Short Messaging Peer to Peer Protocol (SMPP)
10 | https://github.com/Restcomm/cloudhopper-smpp
11 | 2009
12 |
13 |
14 | https://github.com/Restcomm/cloudhopper-smpp
15 | scm:git:https://github.com/Restcomm/cloudhopper-smpp.git
16 | scm:git:git@github.com:Restcomm/cloudhopper-smpp.git
17 | master
18 |
19 |
20 |
21 | org.restcomm
22 | restcomm-parent
23 | 3.0.5
24 |
25 |
26 |
27 | com.cloudhopper.smpp
28 | 7.0.6-3
29 | 7.0.6
30 | 7.0.6
31 | 3.9.6.Final
32 | 1.7.13
33 |
34 | 3.2.5
35 |
36 |
37 |
38 |
39 |
40 | org.restcomm.smpp
41 | ch-commons-util
42 | ${ch-commons-util.version}
43 |
44 |
45 | org.restcomm.smpp
46 | ch-commons-charset
47 | ${ch-commons-charset.version}
48 |
49 |
50 | org.slf4j
51 | slf4j-api
52 | ${slf4j.version}
53 |
54 |
55 | io.netty
56 | netty
57 | ${netty.version}
58 |
59 |
60 |
61 |
62 |
63 | junit
64 | junit
65 | 4.12
66 | test
67 |
68 |
69 | org.restcomm.smpp
70 | ch-commons-gsm
71 | 7.0.4
72 | test
73 |
74 |
75 | ch.qos.logback
76 | logback-classic
77 | 1.1.3
78 | test
79 |
80 |
81 |
82 |
83 |
--------------------------------------------------------------------------------
/src/etc/SMPP_v3_4_Issue1_2.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RestComm/cloudhopper-smpp/99a45b7e9389c79566a369f0f1d7902f20027353/src/etc/SMPP_v3_4_Issue1_2.pdf
--------------------------------------------------------------------------------
/src/etc/SMPP_v5_0.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RestComm/cloudhopper-smpp/99a45b7e9389c79566a369f0f1d7902f20027353/src/etc/SMPP_v5_0.pdf
--------------------------------------------------------------------------------
/src/main/java/com/cloudhopper/smpp/PduAsyncResponse.java:
--------------------------------------------------------------------------------
1 | package com.cloudhopper.smpp;
2 |
3 | /*
4 | * #%L
5 | * ch-smpp
6 | * %%
7 | * Copyright (C) 2009 - 2015 Cloudhopper by Twitter
8 | * %%
9 | * Licensed under the Apache License, Version 2.0 (the "License");
10 | * you may not use this file except in compliance with the License.
11 | * You may obtain a copy of the License at
12 | *
13 | * http://www.apache.org/licenses/LICENSE-2.0
14 | *
15 | * Unless required by applicable law or agreed to in writing, software
16 | * distributed under the License is distributed on an "AS IS" BASIS,
17 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18 | * See the License for the specific language governing permissions and
19 | * limitations under the License.
20 | * #L%
21 | */
22 |
23 | import com.cloudhopper.smpp.pdu.PduRequest;
24 | import com.cloudhopper.smpp.pdu.PduResponse;
25 |
26 | /**
27 | * A container to hold an asynchronous response and include information tracked
28 | * internally by an SmppSession. For example, an instance of this class will
29 | * contain the original request, the response, and a few timestamps.
30 | *
31 | * @author joelauer (twitter: @jjlauer or http://twitter.com/jjlauer)
32 | */
33 | public interface PduAsyncResponse {
34 |
35 | /**
36 | * Gets the original request associated with the response.
37 | * @return The original request
38 | */
39 | public PduRequest getRequest();
40 |
41 | /**
42 | * Gets the response from the remote endpoint.
43 | * @return The response
44 | */
45 | public PduResponse getResponse();
46 |
47 | /**
48 | * Gets the size of the window after this request was added.
49 | * @return The size of the window after this request was added.
50 | */
51 | public int getWindowSize();
52 |
53 | /**
54 | * Gets the amount of time required to accept the request into the session
55 | * send window (for a free slot to open up).
56 | * @return The amount of time (in ms) to accept the request into the send window
57 | */
58 | public long getWindowWaitTime();
59 |
60 | /**
61 | * Gets the amount of time required for the remote endpoint to acknowledge
62 | * the request with a response. This value is based on the time the request
63 | * went out on the wire till a response was received on the wire. Does not
64 | * include any time required waiting for a slot in the window to become
65 | * available.
66 | *
67 | * NOTE: If the window size is > 1, this value can be somewhat misleading.
68 | * The remote endpoint would process X number of requests ahead of this one
69 | * that went out ahead of it in the window. This does represent the total
70 | * response time, but doesn't mean the remote endpoint is this slow at processing
71 | * one request. In cases of high load where the window is always full, the
72 | * windowWaitTime actually represents how fast the remote endpoint is processing
73 | * requests.
74 | * @return The amount of time (in ms) to receive a response from remote endpoint
75 | */
76 | public long getResponseTime();
77 |
78 | /**
79 | * Gets an estimate of the processing time required by the remote endpoint
80 | * to process this request. The value is calculated with the following
81 | * formula: "response time" divided by the "window size" at the time of the
82 | * request.
83 | * @return The amount of estimated time (in ms) to receive a response from
84 | * the remote endpoint just for this request (as opposed to potentially
85 | * this request and all requests ahead of it in the window).
86 | */
87 | public long getEstimatedProcessingTime();
88 |
89 | }
--------------------------------------------------------------------------------
/src/main/java/com/cloudhopper/smpp/SmppBindType.java:
--------------------------------------------------------------------------------
1 | package com.cloudhopper.smpp;
2 |
3 | /*
4 | * #%L
5 | * ch-smpp
6 | * %%
7 | * Copyright (C) 2009 - 2015 Cloudhopper by Twitter
8 | * %%
9 | * Licensed under the Apache License, Version 2.0 (the "License");
10 | * you may not use this file except in compliance with the License.
11 | * You may obtain a copy of the License at
12 | *
13 | * http://www.apache.org/licenses/LICENSE-2.0
14 | *
15 | * Unless required by applicable law or agreed to in writing, software
16 | * distributed under the License is distributed on an "AS IS" BASIS,
17 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18 | * See the License for the specific language governing permissions and
19 | * limitations under the License.
20 | * #L%
21 | */
22 |
23 | /**
24 | * Enumeration of all SMPP session types.
25 | *
26 | * @author joelauer (twitter: @jjlauer or http://twitter.com/jjlauer)
27 | */
28 | public enum SmppBindType {
29 |
30 | TRANSCEIVER,
31 | TRANSMITTER,
32 | RECEIVER
33 |
34 | }
35 |
--------------------------------------------------------------------------------
/src/main/java/com/cloudhopper/smpp/SmppClient.java:
--------------------------------------------------------------------------------
1 | package com.cloudhopper.smpp;
2 |
3 | /*
4 | * #%L
5 | * ch-smpp
6 | * %%
7 | * Copyright (C) 2009 - 2015 Cloudhopper by Twitter
8 | * %%
9 | * Licensed under the Apache License, Version 2.0 (the "License");
10 | * you may not use this file except in compliance with the License.
11 | * You may obtain a copy of the License at
12 | *
13 | * http://www.apache.org/licenses/LICENSE-2.0
14 | *
15 | * Unless required by applicable law or agreed to in writing, software
16 | * distributed under the License is distributed on an "AS IS" BASIS,
17 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18 | * See the License for the specific language governing permissions and
19 | * limitations under the License.
20 | * #L%
21 | */
22 |
23 | import com.cloudhopper.smpp.type.SmppBindException;
24 | import com.cloudhopper.smpp.type.SmppChannelException;
25 | import com.cloudhopper.smpp.type.SmppTimeoutException;
26 | import com.cloudhopper.smpp.type.UnrecoverablePduException;
27 |
28 | /**
29 | * Interface representing an SmppClient.
30 | *
31 | * @author joelauer (twitter: @jjlauer or http://twitter.com/jjlauer)
32 | */
33 | public interface SmppClient {
34 |
35 | /**
36 | * Binds a client to a remote SMPP endpoint by opening the socket, sending
37 | * a bind request, and waiting for a bind response.
38 | * @param config The client session configuration
39 | * @param sessionHandler The session handler
40 | * @return If the bind is successful will be the new session
41 | * @throws SmppTimeoutException Thrown if either the underlying TCP/IP connection
42 | * cannot connect within the "connectTimeout" or we can connect but don't
43 | * receive a response back to the bind request within the "bindTimeout".
44 | * @throws SmppChannelException Thrown if there is an error with the underlying
45 | * TCP/IP connection such as a bad host name or the remote server's port
46 | * is not accepting connections.
47 | * @throws SmppBindException Thrown only in the case where the "bind" request
48 | * was successfully sent to the remote system and we actually got back
49 | * a "bind" response that rejected the bind attempt.
50 | * @throws UnrecoverablePduException Thrown in the case where we were able
51 | * to connect and send our "bind" request, but we got back data that
52 | * was not failed parsing into a PDU.
53 | * @throws InterruptedException Thrown if the calling thread is interrupted
54 | * while we are attempting the bind.
55 | */
56 | public SmppSession bind(SmppSessionConfiguration config, SmppSessionHandler sessionHandler) throws SmppTimeoutException, SmppChannelException, SmppBindException, UnrecoverablePduException, InterruptedException;
57 |
58 | /**
59 | * Destroy a client by ensuring that all session sockets are closed and all
60 | * resources are cleaned up. This method should the last method called
61 | * before discarding or losing a reference to a client. Since this method
62 | * cleans up all resources, make sure that any data you need to access is
63 | * accessed before calling this method. After calling this method
64 | * it is not guaranteed that any other method will correctly work.
65 | */
66 | public void destroy();
67 |
68 | }
69 |
--------------------------------------------------------------------------------
/src/main/java/com/cloudhopper/smpp/SmppServer.java:
--------------------------------------------------------------------------------
1 | package com.cloudhopper.smpp;
2 |
3 | /*
4 | * #%L
5 | * ch-smpp
6 | * %%
7 | * Copyright (C) 2009 - 2015 Cloudhopper by Twitter
8 | * %%
9 | * Licensed under the Apache License, Version 2.0 (the "License");
10 | * you may not use this file except in compliance with the License.
11 | * You may obtain a copy of the License at
12 | *
13 | * http://www.apache.org/licenses/LICENSE-2.0
14 | *
15 | * Unless required by applicable law or agreed to in writing, software
16 | * distributed under the License is distributed on an "AS IS" BASIS,
17 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18 | * See the License for the specific language governing permissions and
19 | * limitations under the License.
20 | * #L%
21 | */
22 |
23 | import com.cloudhopper.smpp.type.SmppChannelException;
24 | import org.jboss.netty.channel.group.ChannelGroup;
25 |
26 | /**
27 | * Interface representing an SmppServer.
28 | *
29 | * @author joelauer (twitter: @jjlauer or http://twitter.com/jjlauer)
30 | */
31 | public interface SmppServer {
32 |
33 | /**
34 | * Returns true if the SMPP server is started.
35 | * @return True if started, otherwise false.
36 | */
37 | public boolean isStarted();
38 |
39 | /**
40 | * Returns true if the SMPP server is stopped.
41 | * @return True if stopped, otherwise false.
42 | */
43 | public boolean isStopped();
44 |
45 | /**
46 | * Returns true if the SMPP server is destroyed.
47 | * @return True if destroyed, otherwise false.
48 | */
49 | public boolean isDestroyed();
50 |
51 | /**
52 | * Starts the SMPP server. Binds all server socket connectors to configured
53 | * ports.
54 | */
55 | public void start() throws SmppChannelException;
56 |
57 | /**
58 | * Stops the SMPP server. Closes all child sockets and then closes all server
59 | * socket connectors by unbinding them from ports. Once stopped, the server
60 | * can be started again. If a server will no longer be used, please follow
61 | * a call to stop by calling {@see #shutdown()}
62 | */
63 | public void stop();
64 |
65 | /**
66 | * Destroys the SMPP server. Ensures the server is first stopped, then
67 | * releases all resources, and unregisters from JMX (if it was enabled).
68 | */
69 | public void destroy();
70 |
71 | public ChannelGroup getChannels();
72 |
73 | public SmppServerCounters getCounters();
74 |
75 | }
76 |
--------------------------------------------------------------------------------
/src/main/java/com/cloudhopper/smpp/SmppServerCounters.java:
--------------------------------------------------------------------------------
1 | package com.cloudhopper.smpp;
2 |
3 | /*
4 | * #%L
5 | * ch-smpp
6 | * %%
7 | * Copyright (C) 2009 - 2015 Cloudhopper by Twitter
8 | * %%
9 | * Licensed under the Apache License, Version 2.0 (the "License");
10 | * you may not use this file except in compliance with the License.
11 | * You may obtain a copy of the License at
12 | *
13 | * http://www.apache.org/licenses/LICENSE-2.0
14 | *
15 | * Unless required by applicable law or agreed to in writing, software
16 | * distributed under the License is distributed on an "AS IS" BASIS,
17 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18 | * See the License for the specific language governing permissions and
19 | * limitations under the License.
20 | * #L%
21 | */
22 |
23 | /**
24 | * Interface defining the counters that will be tracked for an SMPP server.
25 | *
26 | * @author joelauer (twitter: @jjlauer or http://twitter.com/jjlauer)
27 | */
28 | public interface SmppServerCounters {
29 |
30 | /**
31 | * Clears all counters (including session size(s)).
32 | */
33 | public void clear();
34 |
35 | /**
36 | * Resets counters that don't track any state (e.g. session size(s)).
37 | */
38 | public void reset();
39 |
40 | public int getChannelConnects();
41 |
42 | public int getChannelDisconnects();
43 |
44 | public int getBindTimeouts();
45 |
46 | public int getBindRequested();
47 |
48 | public int getSessionCreated();
49 |
50 | public int getSessionDestroyed();
51 |
52 | public int getReceiverSessionSize();
53 |
54 | public int getSessionSize();
55 |
56 | public int getTransceiverSessionSize();
57 |
58 | public int getTransmitterSessionSize();
59 |
60 | }
61 |
--------------------------------------------------------------------------------
/src/main/java/com/cloudhopper/smpp/SmppServerSession.java:
--------------------------------------------------------------------------------
1 | package com.cloudhopper.smpp;
2 |
3 | /*
4 | * #%L
5 | * ch-smpp
6 | * %%
7 | * Copyright (C) 2009 - 2015 Cloudhopper by Twitter
8 | * %%
9 | * Licensed under the Apache License, Version 2.0 (the "License");
10 | * you may not use this file except in compliance with the License.
11 | * You may obtain a copy of the License at
12 | *
13 | * http://www.apache.org/licenses/LICENSE-2.0
14 | *
15 | * Unless required by applicable law or agreed to in writing, software
16 | * distributed under the License is distributed on an "AS IS" BASIS,
17 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18 | * See the License for the specific language governing permissions and
19 | * limitations under the License.
20 | * #L%
21 | */
22 |
23 | /**
24 | * An extended interface for a Server (SMSC) SMPP session.
25 | *
26 | * @author joelauer (twitter: @jjlauer or http://twitter.com/jjlauer)
27 | */
28 | public interface SmppServerSession extends SmppSession {
29 |
30 | /**
31 | * Indicates that the local endpoint (server) is ready to start processing
32 | * requests for the session. Completes the bind process by the remote
33 | * endpoint by setting up the handler for the session, sending back the
34 | * prepared bind response and setting the socket/channel as readable.
35 | *
36 | * Please note that when the SmppServer accepts a new socket connection
37 | * from a client, it reads the bind request, but does not automatically
38 | * send back a bind response. The bind response can only be sent back
39 | * by calling this method to indicate that the server is now fully ready
40 | * to process requests from the client.
41 |
42 | * @param sessionHandler The handler for the session to use for processing
43 | */
44 | public void serverReady(SmppSessionHandler sessionHandler);
45 |
46 | }
47 |
--------------------------------------------------------------------------------
/src/main/java/com/cloudhopper/smpp/SmppSessionCounters.java:
--------------------------------------------------------------------------------
1 | package com.cloudhopper.smpp;
2 |
3 | /*
4 | * #%L
5 | * ch-smpp
6 | * %%
7 | * Copyright (C) 2009 - 2015 Cloudhopper by Twitter
8 | * %%
9 | * Licensed under the Apache License, Version 2.0 (the "License");
10 | * you may not use this file except in compliance with the License.
11 | * You may obtain a copy of the License at
12 | *
13 | * http://www.apache.org/licenses/LICENSE-2.0
14 | *
15 | * Unless required by applicable law or agreed to in writing, software
16 | * distributed under the License is distributed on an "AS IS" BASIS,
17 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18 | * See the License for the specific language governing permissions and
19 | * limitations under the License.
20 | * #L%
21 | */
22 |
23 | import com.cloudhopper.smpp.util.ConcurrentCommandCounter;
24 |
25 | /**
26 | * Interface defining the counters that can be optionally tracked for an SMPP session.
27 | *
28 | * @author joelauer (twitter: @jjlauer or http://twitter.com/jjlauer)
29 | */
30 | public interface SmppSessionCounters {
31 |
32 | public void reset();
33 |
34 | public ConcurrentCommandCounter getRxDataSM();
35 |
36 | public ConcurrentCommandCounter getRxDeliverSM();
37 |
38 | public ConcurrentCommandCounter getRxEnquireLink();
39 |
40 | public ConcurrentCommandCounter getRxSubmitSM();
41 |
42 | public ConcurrentCommandCounter getTxDataSM();
43 |
44 | public ConcurrentCommandCounter getTxDeliverSM();
45 |
46 | public ConcurrentCommandCounter getTxEnquireLink();
47 |
48 | public ConcurrentCommandCounter getTxSubmitSM();
49 |
50 | }
51 |
--------------------------------------------------------------------------------
/src/main/java/com/cloudhopper/smpp/SmppSessionListener.java:
--------------------------------------------------------------------------------
1 | package com.cloudhopper.smpp;
2 |
3 | /*
4 | * #%L
5 | * ch-smpp
6 | * %%
7 | * Copyright (C) 2009 - 2014 Cloudhopper by Twitter
8 | * %%
9 | * Licensed under the Apache License, Version 2.0 (the "License");
10 | * you may not use this file except in compliance with the License.
11 | * You may obtain a copy of the License at
12 | *
13 | * http://www.apache.org/licenses/LICENSE-2.0
14 | *
15 | * Unless required by applicable law or agreed to in writing, software
16 | * distributed under the License is distributed on an "AS IS" BASIS,
17 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18 | * See the License for the specific language governing permissions and
19 | * limitations under the License.
20 | * #L%
21 | */
22 |
23 | import com.cloudhopper.smpp.pdu.Pdu;
24 |
25 | /**
26 | * Low-level PDU traffic listener.
27 | * Could be used for PDU filtering.
28 | * Use with caution.
29 | *
30 | * @author t3hk0d3
31 | */
32 | public interface SmppSessionListener extends SmppSessionHandler {
33 |
34 | /**
35 | * Called when ANY PDU received from connection.
36 | * This method could be used to sniff all incoming SMPP packet traffic,
37 | * and also permit/deny it from futher processing.
38 | * Could be used for advanced packet logging, counters and filtering.
39 | * @param pdu
40 | * @return boolean allow PDU processing. If false PDU would be discarded.
41 | */
42 | public boolean firePduReceived(Pdu pdu);
43 |
44 | /**
45 | * Called when ANY PDU received from connection.
46 | * This method could be used to sniff all outgoing SMPP packet traffic,
47 | * and also permit/deny it from sending.
48 | * Could be used for advanced packet logging, counters and filtering.
49 | * @param pdu
50 | * @return boolean allow PDU sending. If false PDU would be discarded.
51 | */
52 | public boolean firePduDispatch(Pdu pdu);
53 |
54 | }
55 |
--------------------------------------------------------------------------------
/src/main/java/com/cloudhopper/smpp/channel/ChannelUtil.java:
--------------------------------------------------------------------------------
1 | package com.cloudhopper.smpp.channel;
2 |
3 | /*
4 | * #%L
5 | * ch-smpp
6 | * %%
7 | * Copyright (C) 2009 - 2015 Cloudhopper by Twitter
8 | * %%
9 | * Licensed under the Apache License, Version 2.0 (the "License");
10 | * you may not use this file except in compliance with the License.
11 | * You may obtain a copy of the License at
12 | *
13 | * http://www.apache.org/licenses/LICENSE-2.0
14 | *
15 | * Unless required by applicable law or agreed to in writing, software
16 | * distributed under the License is distributed on an "AS IS" BASIS,
17 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18 | * See the License for the specific language governing permissions and
19 | * limitations under the License.
20 | * #L%
21 | */
22 |
23 | import java.net.InetSocketAddress;
24 | import org.jboss.netty.channel.Channel;
25 |
26 | /**
27 | * Utility methods for working with Netty Channels.
28 | *
29 | * @author joelauer (twitter: @jjlauer or http://twitter.com/jjlauer)
30 | */
31 | public class ChannelUtil {
32 |
33 | /**
34 | * Create a name for the channel based on the remote host's IP and port.
35 | */
36 | static public String createChannelName(Channel channel) {
37 | // check if anything is null
38 | if (channel == null || channel.getRemoteAddress() == null) {
39 | return "ChannelWasNull";
40 | }
41 | // create a channel name
42 | if (channel.getRemoteAddress() instanceof InetSocketAddress) {
43 | InetSocketAddress addr = (InetSocketAddress)channel.getRemoteAddress();
44 | // just get the raw IP address
45 | String remoteHostAddr = addr.getAddress().getHostAddress();
46 | int remoteHostPort = addr.getPort();
47 | return remoteHostAddr + ":" + remoteHostPort;
48 | } else {
49 | return channel.getRemoteAddress().toString();
50 | }
51 | }
52 |
53 | static public String getChannelRemoteHost(Channel channel) {
54 | if (channel == null || channel.getRemoteAddress() == null) {
55 | return null;
56 | }
57 | // create a channel name
58 | if (channel.getRemoteAddress() instanceof InetSocketAddress) {
59 | InetSocketAddress addr = (InetSocketAddress)channel.getRemoteAddress();
60 | // just get the raw IP address
61 | return addr.getAddress().getHostAddress();
62 | }
63 | return null;
64 | }
65 |
66 | static public int getChannelRemotePort(Channel channel) {
67 | if (channel == null || channel.getRemoteAddress() == null) {
68 | return 0;
69 | }
70 | // create a channel name
71 | if (channel.getRemoteAddress() instanceof InetSocketAddress) {
72 | InetSocketAddress addr = (InetSocketAddress)channel.getRemoteAddress();
73 | // just get the raw IP address
74 | return addr.getPort();
75 | }
76 | return 0;
77 | }
78 |
79 | }
80 |
--------------------------------------------------------------------------------
/src/main/java/com/cloudhopper/smpp/channel/SmppChannelConstants.java:
--------------------------------------------------------------------------------
1 | package com.cloudhopper.smpp.channel;
2 |
3 | /*
4 | * #%L
5 | * ch-smpp
6 | * %%
7 | * Copyright (C) 2009 - 2015 Cloudhopper by Twitter
8 | * %%
9 | * Licensed under the Apache License, Version 2.0 (the "License");
10 | * you may not use this file except in compliance with the License.
11 | * You may obtain a copy of the License at
12 | *
13 | * http://www.apache.org/licenses/LICENSE-2.0
14 | *
15 | * Unless required by applicable law or agreed to in writing, software
16 | * distributed under the License is distributed on an "AS IS" BASIS,
17 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18 | * See the License for the specific language governing permissions and
19 | * limitations under the License.
20 | * #L%
21 | */
22 |
23 | /**
24 | * Constants used for SMPP channels and pipelines.
25 | *
26 | * @author joelauer (twitter: @jjlauer or http://twitter.com/jjlauer)
27 | */
28 | public class SmppChannelConstants {
29 |
30 | public static final String PIPELINE_SERVER_CONNECTOR_NAME = "smppServerConnector";
31 |
32 | // default channel handler used only during connects
33 | public static final String PIPELINE_CLIENT_CONNECTOR_NAME = "smppClientConnector";
34 |
35 | // channel handlers used for once a session is connected
36 | public static final String PIPELINE_SESSION_THREAD_RENAMER_NAME = "smppSessionThreadRenamer";
37 | public static final String PIPELINE_SESSION_LOGGER_NAME = "smppSessionLogger";
38 | public static final String PIPELINE_SESSION_PDU_DECODER_NAME = "smppSessionPduDecoder";
39 | public static final String PIPELINE_SESSION_WRAPPER_NAME = "smppSessionWrapper";
40 | public static final String PIPELINE_SESSION_SSL_NAME = "smppSessionSSL";
41 | public static final String PIPELINE_SESSION_WRITE_TIMEOUT_NAME = "smppSessionWriteTimeout";
42 |
43 | }
44 |
--------------------------------------------------------------------------------
/src/main/java/com/cloudhopper/smpp/channel/SmppClientConnector.java:
--------------------------------------------------------------------------------
1 | package com.cloudhopper.smpp.channel;
2 |
3 | /*
4 | * #%L
5 | * ch-smpp
6 | * %%
7 | * Copyright (C) 2009 - 2015 Cloudhopper by Twitter
8 | * %%
9 | * Licensed under the Apache License, Version 2.0 (the "License");
10 | * you may not use this file except in compliance with the License.
11 | * You may obtain a copy of the License at
12 | *
13 | * http://www.apache.org/licenses/LICENSE-2.0
14 | *
15 | * Unless required by applicable law or agreed to in writing, software
16 | * distributed under the License is distributed on an "AS IS" BASIS,
17 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18 | * See the License for the specific language governing permissions and
19 | * limitations under the License.
20 | * #L%
21 | */
22 |
23 | import org.jboss.netty.channel.ChannelHandlerContext;
24 | import org.jboss.netty.channel.ChannelPipelineCoverage;
25 | import org.jboss.netty.channel.ChannelStateEvent;
26 | import org.jboss.netty.channel.ExceptionEvent;
27 | import org.jboss.netty.channel.SimpleChannelUpstreamHandler;
28 | import org.jboss.netty.channel.group.ChannelGroup;
29 | import org.slf4j.Logger;
30 | import org.slf4j.LoggerFactory;
31 |
32 | /**
33 | * The default handler used just during a "connect" for a Channel when attempting
34 | * to bind into an SMSC. The reason is that some handler must be added to create
35 | * a channel and then replaced before the actual "bind" is attempted. This
36 | * handler basically does nothing. Until a "bind" request is received by the SMSC,
37 | * nothing should actually be received so its safe to have a handler that does
38 | * nothing.
39 | *
40 | * @author joelauer (twitter: @jjlauer or http://twitter.com/jjlauer)
41 | */
42 | @ChannelPipelineCoverage("all")
43 | public class SmppClientConnector extends SimpleChannelUpstreamHandler {
44 | private static final Logger logger = LoggerFactory.getLogger(SmppClientConnector.class);
45 |
46 | private ChannelGroup channels;
47 |
48 | public SmppClientConnector(ChannelGroup channels) {
49 | this.channels = channels;
50 | }
51 |
52 | @Override
53 | public void channelConnected(ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception {
54 | // called every time a new channel connects
55 | channels.add(e.getChannel());
56 | }
57 |
58 | @Override
59 | public void channelDisconnected(ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception {
60 | // called every time a channel disconnects
61 | channels.remove(e.getChannel());
62 | }
63 |
64 | /**
65 | * Invoked when an exception was raised by an I/O thread or an upstream handler.
66 | * NOTE: Not implementing this causes annoying log statements to STDERR
67 | */
68 | @Override
69 | public void exceptionCaught(ChannelHandlerContext ctx, ExceptionEvent e) throws Exception {
70 | // the client smpp implementation relies on this to catch errors upstream
71 | // however, during a connect sequence, we don't have any upstream handlers
72 | // yet and the framework logged the exceptions to STDERR causing issues
73 | // on the console. So, we'll implement a default handling of it here
74 | // where we just pass it further upstream and basically discard it
75 | ctx.sendUpstream(e);
76 | }
77 | }
--------------------------------------------------------------------------------
/src/main/java/com/cloudhopper/smpp/channel/SmppSessionPduDecoder.java:
--------------------------------------------------------------------------------
1 | package com.cloudhopper.smpp.channel;
2 |
3 | /*
4 | * #%L
5 | * ch-smpp
6 | * %%
7 | * Copyright (C) 2009 - 2015 Cloudhopper by Twitter
8 | * %%
9 | * Licensed under the Apache License, Version 2.0 (the "License");
10 | * you may not use this file except in compliance with the License.
11 | * You may obtain a copy of the License at
12 | *
13 | * http://www.apache.org/licenses/LICENSE-2.0
14 | *
15 | * Unless required by applicable law or agreed to in writing, software
16 | * distributed under the License is distributed on an "AS IS" BASIS,
17 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18 | * See the License for the specific language governing permissions and
19 | * limitations under the License.
20 | * #L%
21 | */
22 |
23 | import com.cloudhopper.smpp.transcoder.PduTranscoder;
24 | import org.jboss.netty.buffer.ChannelBuffer;
25 | import org.jboss.netty.channel.Channel;
26 | import org.jboss.netty.channel.ChannelHandlerContext;
27 | import org.jboss.netty.handler.codec.frame.FrameDecoder;
28 |
29 | /**
30 | * Channel handler responsible for decoding a ChannelBuffer into a PDU. A
31 | * decoded PDU is then passed up the pipeline for further processing.
32 | *
33 | * @author joelauer (twitter: @jjlauer or http://twitter.com/jjlauer)
34 | */
35 | public class SmppSessionPduDecoder extends FrameDecoder {
36 |
37 | private final PduTranscoder transcoder;
38 |
39 | public SmppSessionPduDecoder(PduTranscoder transcoder) {
40 | this.transcoder = transcoder;
41 | }
42 |
43 | @Override
44 | protected Object decode(ChannelHandlerContext ctx, Channel channel, ChannelBuffer buffer) throws Exception {
45 | // try to decode the frame into a PDU
46 | // NOTE: this already returns null if there isn't enough data yet
47 | return transcoder.decode(buffer);
48 | }
49 |
50 | }
51 |
--------------------------------------------------------------------------------
/src/main/java/com/cloudhopper/smpp/channel/SmppSessionThreadRenamer.java:
--------------------------------------------------------------------------------
1 | package com.cloudhopper.smpp.channel;
2 |
3 | /*
4 | * #%L
5 | * ch-smpp
6 | * %%
7 | * Copyright (C) 2009 - 2015 Cloudhopper by Twitter
8 | * %%
9 | * Licensed under the Apache License, Version 2.0 (the "License");
10 | * you may not use this file except in compliance with the License.
11 | * You may obtain a copy of the License at
12 | *
13 | * http://www.apache.org/licenses/LICENSE-2.0
14 | *
15 | * Unless required by applicable law or agreed to in writing, software
16 | * distributed under the License is distributed on an "AS IS" BASIS,
17 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18 | * See the License for the specific language governing permissions and
19 | * limitations under the License.
20 | * #L%
21 | */
22 |
23 |
24 | import org.jboss.netty.channel.ChannelEvent;
25 | import org.jboss.netty.channel.ChannelHandlerContext;
26 | import org.jboss.netty.channel.ChannelPipelineCoverage;
27 | import org.jboss.netty.channel.ChannelUpstreamHandler;
28 |
29 | /**
30 | * Channel handler responsible for renaming the current thread, passing the
31 | * event upstream, then renaming the thread back after its done processing. This
32 | * handler should be the first one in the pipeline to make sure all handlers
33 | * after it have the correct thread name for proper logging.
34 | *
35 | * @author joelauer (twitter: @jjlauer or http://twitter.com/jjlauer)
36 | */
37 | @ChannelPipelineCoverage("one")
38 | public class SmppSessionThreadRenamer implements ChannelUpstreamHandler {
39 |
40 | private String threadName;
41 |
42 | public SmppSessionThreadRenamer(String threadName) {
43 | this.threadName = threadName;
44 | }
45 |
46 | public String getThreadName() {
47 | return this.threadName;
48 | }
49 |
50 | public void setThreadName(String value) {
51 | this.threadName = value;
52 | }
53 |
54 | @Override
55 | public void handleUpstream(ChannelHandlerContext ctx, ChannelEvent e) throws Exception {
56 | // always rename the current thread and then rename it back
57 | String currentThreadName = Thread.currentThread().getName();
58 | Thread.currentThread().setName(threadName);
59 | ctx.sendUpstream(e);
60 | Thread.currentThread().setName(currentThreadName);
61 | }
62 | }
63 |
--------------------------------------------------------------------------------
/src/main/java/com/cloudhopper/smpp/channel/SmppSessionWrapper.java:
--------------------------------------------------------------------------------
1 | package com.cloudhopper.smpp.channel;
2 |
3 | /*
4 | * #%L
5 | * ch-smpp
6 | * %%
7 | * Copyright (C) 2009 - 2015 Cloudhopper by Twitter
8 | * %%
9 | * Licensed under the Apache License, Version 2.0 (the "License");
10 | * you may not use this file except in compliance with the License.
11 | * You may obtain a copy of the License at
12 | *
13 | * http://www.apache.org/licenses/LICENSE-2.0
14 | *
15 | * Unless required by applicable law or agreed to in writing, software
16 | * distributed under the License is distributed on an "AS IS" BASIS,
17 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18 | * See the License for the specific language governing permissions and
19 | * limitations under the License.
20 | * #L%
21 | */
22 |
23 | import com.cloudhopper.smpp.impl.SmppSessionChannelListener;
24 | import com.cloudhopper.smpp.pdu.Pdu;
25 | import org.jboss.netty.channel.ChannelHandlerContext;
26 | import org.jboss.netty.channel.ChannelPipelineCoverage;
27 | import org.jboss.netty.channel.ChannelStateEvent;
28 | import org.jboss.netty.channel.ExceptionEvent;
29 | import org.jboss.netty.channel.MessageEvent;
30 | import org.jboss.netty.channel.SimpleChannelHandler;
31 | import org.slf4j.Logger;
32 | import org.slf4j.LoggerFactory;
33 |
34 | /**
35 | *
36 | * @author joelauer (twitter: @jjlauer or http://twitter.com/jjlauer)
37 | */
38 | @ChannelPipelineCoverage("one")
39 | public class SmppSessionWrapper extends SimpleChannelHandler {
40 | private static final Logger logger = LoggerFactory.getLogger(SmppSessionWrapper.class);
41 |
42 | private SmppSessionChannelListener listener;
43 |
44 | public SmppSessionWrapper(SmppSessionChannelListener listener) {
45 | this.listener = listener;
46 | }
47 |
48 | @Override
49 | public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception {
50 | if (e.getMessage() instanceof Pdu) {
51 | Pdu pdu = (Pdu)e.getMessage();
52 | this.listener.firePduReceived(pdu);
53 | }
54 | }
55 |
56 | /**
57 | * Invoked when an exception was raised by an I/O thread or an upstream handler.
58 | */
59 | @Override
60 | public void exceptionCaught(ChannelHandlerContext ctx, ExceptionEvent e) throws Exception {
61 | //logger.warn("Exception triggered in upstream ChannelHandler: {}", e.getCause());
62 | this.listener.fireExceptionThrown(e.getCause());
63 | }
64 |
65 | /**
66 | * Invoked when a Channel was disconnected from its remote peer.
67 | */
68 | @Override
69 | public void channelDisconnected(ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception {
70 | //logger.info(e.toString());
71 | //ctx.sendUpstream(e);
72 | }
73 |
74 | /**
75 | * Invoked when a Channel was unbound from the current local address.
76 | */
77 | @Override
78 | public void channelUnbound(ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception {
79 | //logger.info(e.toString());
80 | }
81 |
82 | /**
83 | * Invoked when a Channel was closed and all its related resources were released.
84 | */
85 | @Override
86 | public void channelClosed(ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception {
87 | //logger.info(e.toString());
88 | this.listener.fireChannelClosed();
89 | }
90 | }
--------------------------------------------------------------------------------
/src/main/java/com/cloudhopper/smpp/impl/DefaultPduAsyncResponse.java:
--------------------------------------------------------------------------------
1 | package com.cloudhopper.smpp.impl;
2 |
3 | /*
4 | * #%L
5 | * ch-smpp
6 | * %%
7 | * Copyright (C) 2009 - 2015 Cloudhopper by Twitter
8 | * %%
9 | * Licensed under the Apache License, Version 2.0 (the "License");
10 | * you may not use this file except in compliance with the License.
11 | * You may obtain a copy of the License at
12 | *
13 | * http://www.apache.org/licenses/LICENSE-2.0
14 | *
15 | * Unless required by applicable law or agreed to in writing, software
16 | * distributed under the License is distributed on an "AS IS" BASIS,
17 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18 | * See the License for the specific language governing permissions and
19 | * limitations under the License.
20 | * #L%
21 | */
22 |
23 | import com.cloudhopper.commons.util.HexUtil;
24 | import com.cloudhopper.commons.util.windowing.WindowFuture;
25 | import com.cloudhopper.smpp.PduAsyncResponse;
26 | import com.cloudhopper.smpp.pdu.PduRequest;
27 | import com.cloudhopper.smpp.pdu.PduResponse;
28 |
29 | /**
30 | * Default implementation of an SmppAsyncResponse.
31 | *
32 | * @author joelauer (twitter: @jjlauer or http://twitter.com/jjlauer)
33 | */
34 | public class DefaultPduAsyncResponse implements PduAsyncResponse {
35 | // we internally "wrap" a PDU window future
36 | private final WindowFuture future;
37 |
38 | public DefaultPduAsyncResponse(WindowFuture future) {
39 | this.future = future;
40 | }
41 |
42 | @Override
43 | public PduRequest getRequest() {
44 | return future.getRequest();
45 | }
46 |
47 | @Override
48 | public PduResponse getResponse() {
49 | return future.getResponse();
50 | }
51 |
52 | @Override
53 | public int getWindowSize() {
54 | return future.getWindowSize();
55 | }
56 |
57 | @Override
58 | public long getWindowWaitTime() {
59 | return future.getOfferToAcceptTime();
60 | }
61 |
62 | @Override
63 | public long getResponseTime() {
64 | return future.getAcceptToDoneTime();
65 | }
66 |
67 | @Override
68 | public long getEstimatedProcessingTime() {
69 | long responseTime = getResponseTime();
70 | if (responseTime == 0 || future.getWindowSize() == 0) {
71 | return 0;
72 | }
73 | return (responseTime / future.getWindowSize());
74 | }
75 |
76 | @Override
77 | public String toString() {
78 | StringBuilder buf = new StringBuilder(100);
79 | buf.append("smpp_async_resp: seqNum [0x");
80 | buf.append(HexUtil.toHexString(this.future.getKey()));
81 | buf.append("] windowSize [");
82 | buf.append(getWindowSize());
83 | buf.append("] windowWaitTime [");
84 | buf.append(getWindowWaitTime());
85 | buf.append(" ms] responseTime [");
86 | buf.append(getResponseTime());
87 | buf.append(" ms] estProcessingTime [");
88 | buf.append(getEstimatedProcessingTime());
89 | buf.append(" ms] reqType [");
90 | buf.append(getRequest().getName());
91 | buf.append("] respType [");
92 | buf.append(getResponse().getName());
93 | buf.append("]");
94 | return buf.toString();
95 | }
96 |
97 | }
98 |
--------------------------------------------------------------------------------
/src/main/java/com/cloudhopper/smpp/impl/DefaultSmppSessionCounters.java:
--------------------------------------------------------------------------------
1 | package com.cloudhopper.smpp.impl;
2 |
3 | /*
4 | * #%L
5 | * ch-smpp
6 | * %%
7 | * Copyright (C) 2009 - 2015 Cloudhopper by Twitter
8 | * %%
9 | * Licensed under the Apache License, Version 2.0 (the "License");
10 | * you may not use this file except in compliance with the License.
11 | * You may obtain a copy of the License at
12 | *
13 | * http://www.apache.org/licenses/LICENSE-2.0
14 | *
15 | * Unless required by applicable law or agreed to in writing, software
16 | * distributed under the License is distributed on an "AS IS" BASIS,
17 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18 | * See the License for the specific language governing permissions and
19 | * limitations under the License.
20 | * #L%
21 | */
22 |
23 | import com.cloudhopper.smpp.SmppSessionCounters;
24 | import com.cloudhopper.smpp.util.ConcurrentCommandCounter;
25 |
26 | /**
27 | * Default implementation of a SmppServerCounters interface.
28 | *
29 | * @author joelauer (twitter: @jjlauer or http://twitter.com/jjlauer)
30 | */
31 | public class DefaultSmppSessionCounters implements SmppSessionCounters {
32 |
33 | private ConcurrentCommandCounter txSubmitSM;
34 | private ConcurrentCommandCounter txDeliverSM;
35 | private ConcurrentCommandCounter txEnquireLink;
36 | private ConcurrentCommandCounter txDataSM;
37 | private ConcurrentCommandCounter rxSubmitSM;
38 | private ConcurrentCommandCounter rxDeliverSM;
39 | private ConcurrentCommandCounter rxEnquireLink;
40 | private ConcurrentCommandCounter rxDataSM;
41 |
42 | public DefaultSmppSessionCounters() {
43 | this.txSubmitSM = new ConcurrentCommandCounter();
44 | this.txDeliverSM = new ConcurrentCommandCounter();
45 | this.txEnquireLink = new ConcurrentCommandCounter();
46 | this.txDataSM = new ConcurrentCommandCounter();
47 | this.rxSubmitSM = new ConcurrentCommandCounter();
48 | this.rxDeliverSM = new ConcurrentCommandCounter();
49 | this.rxEnquireLink = new ConcurrentCommandCounter();
50 | this.rxDataSM = new ConcurrentCommandCounter();
51 | }
52 |
53 | @Override
54 | public void reset() {
55 | this.txSubmitSM.reset();
56 | this.txDeliverSM.reset();
57 | this.txEnquireLink.reset();
58 | this.txDataSM.reset();
59 | this.rxSubmitSM.reset();
60 | this.rxDeliverSM.reset();
61 | this.rxEnquireLink.reset();
62 | this.rxDataSM.reset();
63 | }
64 |
65 | @Override
66 | public ConcurrentCommandCounter getRxDataSM() {
67 | return rxDataSM;
68 | }
69 |
70 | @Override
71 | public ConcurrentCommandCounter getRxDeliverSM() {
72 | return rxDeliverSM;
73 | }
74 |
75 | @Override
76 | public ConcurrentCommandCounter getRxEnquireLink() {
77 | return rxEnquireLink;
78 | }
79 |
80 | @Override
81 | public ConcurrentCommandCounter getRxSubmitSM() {
82 | return rxSubmitSM;
83 | }
84 |
85 | @Override
86 | public ConcurrentCommandCounter getTxDataSM() {
87 | return txDataSM;
88 | }
89 |
90 | @Override
91 | public ConcurrentCommandCounter getTxDeliverSM() {
92 | return txDeliverSM;
93 | }
94 |
95 | @Override
96 | public ConcurrentCommandCounter getTxEnquireLink() {
97 | return txEnquireLink;
98 | }
99 |
100 | @Override
101 | public ConcurrentCommandCounter getTxSubmitSM() {
102 | return txSubmitSM;
103 | }
104 | }
105 |
--------------------------------------------------------------------------------
/src/main/java/com/cloudhopper/smpp/impl/SmppSessionChannelListener.java:
--------------------------------------------------------------------------------
1 | package com.cloudhopper.smpp.impl;
2 |
3 | /*
4 | * #%L
5 | * ch-smpp
6 | * %%
7 | * Copyright (C) 2009 - 2015 Cloudhopper by Twitter
8 | * %%
9 | * Licensed under the Apache License, Version 2.0 (the "License");
10 | * you may not use this file except in compliance with the License.
11 | * You may obtain a copy of the License at
12 | *
13 | * http://www.apache.org/licenses/LICENSE-2.0
14 | *
15 | * Unless required by applicable law or agreed to in writing, software
16 | * distributed under the License is distributed on an "AS IS" BASIS,
17 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18 | * See the License for the specific language governing permissions and
19 | * limitations under the License.
20 | * #L%
21 | */
22 |
23 | import com.cloudhopper.smpp.pdu.Pdu;
24 |
25 | /**
26 | * Interface for listening for events on an SmppSessionChannelHandler.
27 | *
28 | * @author joelauer (twitter: @jjlauer or http://twitter.com/jjlauer)
29 | */
30 | public interface SmppSessionChannelListener {
31 |
32 | /**
33 | * Fired when a PDU was successfully decoded and received on this Channel.
34 | * @param pdu The PDU decoded from the Channel
35 | */
36 | public void firePduReceived(Pdu pdu);
37 |
38 | /**
39 | * Fired when an exception was raised by an I/O thread or an upstream handler.
40 | * @param t The exception thrown
41 | */
42 | public void fireExceptionThrown(Throwable t);
43 |
44 | /**
45 | * Fired when the Channel is closed (reached EOF or timed out)
46 | */
47 | public void fireChannelClosed();
48 |
49 | }
50 |
--------------------------------------------------------------------------------
/src/main/java/com/cloudhopper/smpp/jmx/DefaultSmppServerMXBean.java:
--------------------------------------------------------------------------------
1 | package com.cloudhopper.smpp.jmx;
2 |
3 | /*
4 | * #%L
5 | * ch-smpp
6 | * %%
7 | * Copyright (C) 2009 - 2015 Cloudhopper by Twitter
8 | * %%
9 | * Licensed under the Apache License, Version 2.0 (the "License");
10 | * you may not use this file except in compliance with the License.
11 | * You may obtain a copy of the License at
12 | *
13 | * http://www.apache.org/licenses/LICENSE-2.0
14 | *
15 | * Unless required by applicable law or agreed to in writing, software
16 | * distributed under the License is distributed on an "AS IS" BASIS,
17 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18 | * See the License for the specific language governing permissions and
19 | * limitations under the License.
20 | * #L%
21 | */
22 |
23 | import com.cloudhopper.smpp.type.SmppChannelException;
24 |
25 | /**
26 | * Defines the interface for managing an SmppServer.
27 | *
28 | * @author joelauer
29 | */
30 | public interface DefaultSmppServerMXBean {
31 |
32 | public boolean isStarted();
33 |
34 | public boolean isStopped();
35 |
36 | public boolean isDestroyed();
37 |
38 | public void start() throws SmppChannelException;
39 |
40 | public void stop();
41 |
42 | public void destroy();
43 |
44 | // access to various configuration, stats, and counters useful for monitoring
45 |
46 | public void resetCounters();
47 |
48 | public int getSessionSize();
49 |
50 | public int getTransceiverSessionSize();
51 |
52 | public int getTransmitterSessionSize();
53 |
54 | public int getReceiverSessionSize();
55 |
56 | public int getMaxConnectionSize();
57 |
58 | public int getConnectionSize();
59 |
60 | public long getBindTimeout();
61 |
62 | public boolean isNonBlockingSocketsEnabled();
63 |
64 | public boolean isReuseAddress();
65 |
66 | public int getChannelConnects();
67 |
68 | public int getChannelDisconnects();
69 |
70 | public int getBindTimeouts();
71 |
72 | public int getBindRequested();
73 |
74 | public int getSessionCreated();
75 |
76 | public int getSessionDestroyed();
77 |
78 | }
79 |
--------------------------------------------------------------------------------
/src/main/java/com/cloudhopper/smpp/pdu/AlertNotification.java:
--------------------------------------------------------------------------------
1 | package com.cloudhopper.smpp.pdu;
2 |
3 | /*
4 | * #%L
5 | * ch-smpp
6 | * %%
7 | * Copyright (C) 2009 - 2015 Cloudhopper by Twitter
8 | * %%
9 | * Licensed under the Apache License, Version 2.0 (the "License");
10 | * you may not use this file except in compliance with the License.
11 | * You may obtain a copy of the License at
12 | *
13 | * http://www.apache.org/licenses/LICENSE-2.0
14 | *
15 | * Unless required by applicable law or agreed to in writing, software
16 | * distributed under the License is distributed on an "AS IS" BASIS,
17 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18 | * See the License for the specific language governing permissions and
19 | * limitations under the License.
20 | * #L%
21 | */
22 |
23 | import org.jboss.netty.buffer.ChannelBuffer;
24 |
25 | import com.cloudhopper.commons.util.StringUtil;
26 | import com.cloudhopper.smpp.SmppConstants;
27 | import com.cloudhopper.smpp.type.Address;
28 | import com.cloudhopper.smpp.type.RecoverablePduException;
29 | import com.cloudhopper.smpp.type.UnrecoverablePduException;
30 | import com.cloudhopper.smpp.util.ChannelBufferUtil;
31 | import com.cloudhopper.smpp.util.PduUtil;
32 |
33 | public class AlertNotification extends Pdu {
34 |
35 | protected Address sourceAddress;
36 | protected Address esmeAddress;
37 |
38 | public AlertNotification(){
39 | super( SmppConstants.CMD_ID_ALERT_NOTIFICATION, "alert_notification", true );
40 | }
41 |
42 | public Address getSourceAddress() {
43 | return this.sourceAddress;
44 | }
45 |
46 | public void setSourceAddress(Address value) {
47 | this.sourceAddress = value;
48 | }
49 |
50 | public Address getEsmeAddress() {
51 | return this.esmeAddress;
52 | }
53 |
54 | public void setEsmeAddress(Address value) {
55 | this.esmeAddress = value;
56 | }
57 |
58 | @Override
59 | protected int calculateByteSizeOfBody(){
60 | int bodyLength = 0;
61 | bodyLength += PduUtil.calculateByteSizeOfAddress(this.sourceAddress);
62 | bodyLength += PduUtil.calculateByteSizeOfAddress(this.esmeAddress);
63 | return bodyLength;
64 | }
65 |
66 | @Override
67 | public void readBody( ChannelBuffer buffer ) throws UnrecoverablePduException, RecoverablePduException{
68 | this.sourceAddress = ChannelBufferUtil.readAddress(buffer);
69 | this.esmeAddress = ChannelBufferUtil.readAddress(buffer);
70 | }
71 |
72 | @Override
73 | public void writeBody( ChannelBuffer buffer ) throws UnrecoverablePduException, RecoverablePduException{
74 | ChannelBufferUtil.writeAddress(buffer, this.sourceAddress);
75 | ChannelBufferUtil.writeAddress(buffer, this.esmeAddress);
76 | }
77 |
78 | @Override
79 | protected void appendBodyToString( StringBuilder buffer ){
80 | buffer.append("( sourceAddr [");
81 | buffer.append(StringUtil.toStringWithNullAsEmpty(this.sourceAddress));
82 | buffer.append("] esmeAddr [");
83 | buffer.append(StringUtil.toStringWithNullAsEmpty(this.esmeAddress));
84 | buffer.append("])");
85 | }
86 |
87 | }
88 |
--------------------------------------------------------------------------------
/src/main/java/com/cloudhopper/smpp/pdu/BaseBindResp.java:
--------------------------------------------------------------------------------
1 | package com.cloudhopper.smpp.pdu;
2 |
3 | /*
4 | * #%L
5 | * ch-smpp
6 | * %%
7 | * Copyright (C) 2009 - 2015 Cloudhopper by Twitter
8 | * %%
9 | * Licensed under the Apache License, Version 2.0 (the "License");
10 | * you may not use this file except in compliance with the License.
11 | * You may obtain a copy of the License at
12 | *
13 | * http://www.apache.org/licenses/LICENSE-2.0
14 | *
15 | * Unless required by applicable law or agreed to in writing, software
16 | * distributed under the License is distributed on an "AS IS" BASIS,
17 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18 | * See the License for the specific language governing permissions and
19 | * limitations under the License.
20 | * #L%
21 | */
22 |
23 | import com.cloudhopper.smpp.type.UnrecoverablePduException;
24 | import com.cloudhopper.smpp.type.RecoverablePduException;
25 | import com.cloudhopper.commons.util.StringUtil;
26 | import com.cloudhopper.smpp.util.ChannelBufferUtil;
27 | import com.cloudhopper.smpp.util.PduUtil;
28 | import org.jboss.netty.buffer.ChannelBuffer;
29 |
30 | /**
31 | *
32 | * @author joelauer (twitter: @jjlauer or http://twitter.com/jjlauer)
33 | */
34 | public abstract class BaseBindResp extends PduResponse {
35 |
36 | private String systemId;
37 |
38 | public BaseBindResp(int commandId, String name) {
39 | super(commandId, name);
40 | }
41 |
42 | public void setSystemId(String value) {
43 | this.systemId = value;
44 | }
45 |
46 | public String getSystemId() {
47 | return this.systemId;
48 | }
49 |
50 | @Override
51 | public void readBody(ChannelBuffer buffer) throws UnrecoverablePduException, RecoverablePduException {
52 | // the body may or may not contain a systemId -- the helper utility
53 | // method will take care of returning null if there aren't any readable bytes
54 | this.systemId = ChannelBufferUtil.readNullTerminatedString(buffer);
55 | }
56 |
57 | @Override
58 | public int calculateByteSizeOfBody() {
59 | int bodyLength = 0;
60 | bodyLength += PduUtil.calculateByteSizeOfNullTerminatedString(this.systemId);
61 | return bodyLength;
62 | }
63 |
64 | @Override
65 | public void writeBody(ChannelBuffer buffer) throws UnrecoverablePduException, RecoverablePduException {
66 | ChannelBufferUtil.writeNullTerminatedString(buffer, this.systemId);
67 | }
68 |
69 | @Override
70 | public void appendBodyToString(StringBuilder buffer) {
71 | buffer.append("systemId [");
72 | buffer.append(StringUtil.toStringWithNullAsEmpty(this.systemId));
73 | buffer.append("]");
74 | }
75 | }
--------------------------------------------------------------------------------
/src/main/java/com/cloudhopper/smpp/pdu/BaseSmResp.java:
--------------------------------------------------------------------------------
1 | package com.cloudhopper.smpp.pdu;
2 |
3 | /*
4 | * #%L
5 | * ch-smpp
6 | * %%
7 | * Copyright (C) 2009 - 2015 Cloudhopper by Twitter
8 | * %%
9 | * Licensed under the Apache License, Version 2.0 (the "License");
10 | * you may not use this file except in compliance with the License.
11 | * You may obtain a copy of the License at
12 | *
13 | * http://www.apache.org/licenses/LICENSE-2.0
14 | *
15 | * Unless required by applicable law or agreed to in writing, software
16 | * distributed under the License is distributed on an "AS IS" BASIS,
17 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18 | * See the License for the specific language governing permissions and
19 | * limitations under the License.
20 | * #L%
21 | */
22 |
23 | import com.cloudhopper.smpp.type.UnrecoverablePduException;
24 | import com.cloudhopper.smpp.type.RecoverablePduException;
25 | import com.cloudhopper.commons.util.StringUtil;
26 | import com.cloudhopper.smpp.util.ChannelBufferUtil;
27 | import com.cloudhopper.smpp.util.PduUtil;
28 | import org.jboss.netty.buffer.ChannelBuffer;
29 |
30 | /**
31 | *
32 | * @author joelauer (twitter: @jjlauer or http://twitter.com/jjlauer)
33 | */
34 | public abstract class BaseSmResp extends PduResponse {
35 |
36 | private String messageId;
37 |
38 | public BaseSmResp(int commandId, String name) {
39 | super(commandId, name);
40 | }
41 |
42 | public String getMessageId() {
43 | return this.messageId;
44 | }
45 |
46 | public void setMessageId(String value) {
47 | this.messageId = value;
48 | }
49 |
50 | @Override
51 | public void readBody(ChannelBuffer buffer) throws UnrecoverablePduException, RecoverablePduException {
52 | // the body may or may not contain a messageId -- the helper utility
53 | // method will take care of returning null if there aren't any readable bytes
54 | this.messageId = ChannelBufferUtil.readNullTerminatedString(buffer);
55 | }
56 |
57 | @Override
58 | public int calculateByteSizeOfBody() {
59 | int bodyLength = 0;
60 | bodyLength += PduUtil.calculateByteSizeOfNullTerminatedString(this.messageId);
61 | return bodyLength;
62 | }
63 |
64 | @Override
65 | public void writeBody(ChannelBuffer buffer) throws UnrecoverablePduException, RecoverablePduException {
66 | // when this PDU was parsed, it's possible it was missing the messageId instead
67 | // of having a NULL messageId. If that's the case, the commandLength will be just
68 | // enough for the headers (and theoretically any optional TLVs). Don't try to
69 | // write the NULL byte for that case.
70 | // See special note in 4.4.2 of SMPP 3.4 spec
71 | if (!((buffer.writableBytes() == 0) && (this.messageId == null))) {
72 | ChannelBufferUtil.writeNullTerminatedString(buffer, this.messageId);
73 | }
74 | }
75 |
76 | @Override
77 | public void appendBodyToString(StringBuilder buffer) {
78 | buffer.append("(messageId [");
79 | buffer.append(StringUtil.toStringWithNullAsEmpty(this.messageId));
80 | buffer.append("])");
81 | }
82 | }
--------------------------------------------------------------------------------
/src/main/java/com/cloudhopper/smpp/pdu/BindReceiver.java:
--------------------------------------------------------------------------------
1 | package com.cloudhopper.smpp.pdu;
2 |
3 | /*
4 | * #%L
5 | * ch-smpp
6 | * %%
7 | * Copyright (C) 2009 - 2015 Cloudhopper by Twitter
8 | * %%
9 | * Licensed under the Apache License, Version 2.0 (the "License");
10 | * you may not use this file except in compliance with the License.
11 | * You may obtain a copy of the License at
12 | *
13 | * http://www.apache.org/licenses/LICENSE-2.0
14 | *
15 | * Unless required by applicable law or agreed to in writing, software
16 | * distributed under the License is distributed on an "AS IS" BASIS,
17 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18 | * See the License for the specific language governing permissions and
19 | * limitations under the License.
20 | * #L%
21 | */
22 |
23 | import com.cloudhopper.smpp.SmppConstants;
24 |
25 | /**
26 | *
27 | * @author joelauer (twitter: @jjlauer or http://twitter.com/jjlauer)
28 | */
29 | public class BindReceiver extends BaseBind {
30 |
31 | public BindReceiver() {
32 | super(SmppConstants.CMD_ID_BIND_RECEIVER, "bind_receiver");
33 | }
34 |
35 | @Override
36 | public BindReceiverResp createResponse() {
37 | BindReceiverResp resp = new BindReceiverResp();
38 | resp.setSequenceNumber(this.getSequenceNumber());
39 | return resp;
40 | }
41 |
42 | @Override
43 | public Class getResponseClass() {
44 | return BindReceiverResp.class;
45 | }
46 |
47 | }
--------------------------------------------------------------------------------
/src/main/java/com/cloudhopper/smpp/pdu/BindReceiverResp.java:
--------------------------------------------------------------------------------
1 | package com.cloudhopper.smpp.pdu;
2 |
3 | /*
4 | * #%L
5 | * ch-smpp
6 | * %%
7 | * Copyright (C) 2009 - 2015 Cloudhopper by Twitter
8 | * %%
9 | * Licensed under the Apache License, Version 2.0 (the "License");
10 | * you may not use this file except in compliance with the License.
11 | * You may obtain a copy of the License at
12 | *
13 | * http://www.apache.org/licenses/LICENSE-2.0
14 | *
15 | * Unless required by applicable law or agreed to in writing, software
16 | * distributed under the License is distributed on an "AS IS" BASIS,
17 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18 | * See the License for the specific language governing permissions and
19 | * limitations under the License.
20 | * #L%
21 | */
22 |
23 | import com.cloudhopper.smpp.SmppConstants;
24 |
25 | /**
26 | *
27 | * @author joelauer (twitter: @jjlauer or http://twitter.com/jjlauer)
28 | */
29 | public class BindReceiverResp extends BaseBindResp {
30 |
31 | public BindReceiverResp() {
32 | super(SmppConstants.CMD_ID_BIND_RECEIVER_RESP, "bind_receiver_resp");
33 | }
34 |
35 | }
--------------------------------------------------------------------------------
/src/main/java/com/cloudhopper/smpp/pdu/BindTransceiver.java:
--------------------------------------------------------------------------------
1 | package com.cloudhopper.smpp.pdu;
2 |
3 | /*
4 | * #%L
5 | * ch-smpp
6 | * %%
7 | * Copyright (C) 2009 - 2015 Cloudhopper by Twitter
8 | * %%
9 | * Licensed under the Apache License, Version 2.0 (the "License");
10 | * you may not use this file except in compliance with the License.
11 | * You may obtain a copy of the License at
12 | *
13 | * http://www.apache.org/licenses/LICENSE-2.0
14 | *
15 | * Unless required by applicable law or agreed to in writing, software
16 | * distributed under the License is distributed on an "AS IS" BASIS,
17 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18 | * See the License for the specific language governing permissions and
19 | * limitations under the License.
20 | * #L%
21 | */
22 |
23 | import com.cloudhopper.smpp.SmppConstants;
24 |
25 | /**
26 | *
27 | * @author joelauer (twitter: @jjlauer or http://twitter.com/jjlauer)
28 | */
29 | public class BindTransceiver extends BaseBind {
30 |
31 | public BindTransceiver() {
32 | super(SmppConstants.CMD_ID_BIND_TRANSCEIVER, "bind_transceiver");
33 | }
34 |
35 | @Override
36 | public BindTransceiverResp createResponse() {
37 | BindTransceiverResp resp = new BindTransceiverResp();
38 | resp.setSequenceNumber(this.getSequenceNumber());
39 | return resp;
40 | }
41 |
42 | @Override
43 | public Class getResponseClass() {
44 | return BindTransceiverResp.class;
45 | }
46 |
47 | }
--------------------------------------------------------------------------------
/src/main/java/com/cloudhopper/smpp/pdu/BindTransceiverResp.java:
--------------------------------------------------------------------------------
1 | package com.cloudhopper.smpp.pdu;
2 |
3 | /*
4 | * #%L
5 | * ch-smpp
6 | * %%
7 | * Copyright (C) 2009 - 2015 Cloudhopper by Twitter
8 | * %%
9 | * Licensed under the Apache License, Version 2.0 (the "License");
10 | * you may not use this file except in compliance with the License.
11 | * You may obtain a copy of the License at
12 | *
13 | * http://www.apache.org/licenses/LICENSE-2.0
14 | *
15 | * Unless required by applicable law or agreed to in writing, software
16 | * distributed under the License is distributed on an "AS IS" BASIS,
17 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18 | * See the License for the specific language governing permissions and
19 | * limitations under the License.
20 | * #L%
21 | */
22 |
23 | import com.cloudhopper.smpp.SmppConstants;
24 |
25 | /**
26 | *
27 | * @author joelauer (twitter: @jjlauer or http://twitter.com/jjlauer)
28 | */
29 | public class BindTransceiverResp extends BaseBindResp {
30 |
31 | public BindTransceiverResp() {
32 | super(SmppConstants.CMD_ID_BIND_TRANSCEIVER_RESP, "bind_transceiver_resp");
33 | }
34 |
35 | }
--------------------------------------------------------------------------------
/src/main/java/com/cloudhopper/smpp/pdu/BindTransmitter.java:
--------------------------------------------------------------------------------
1 | package com.cloudhopper.smpp.pdu;
2 |
3 | /*
4 | * #%L
5 | * ch-smpp
6 | * %%
7 | * Copyright (C) 2009 - 2015 Cloudhopper by Twitter
8 | * %%
9 | * Licensed under the Apache License, Version 2.0 (the "License");
10 | * you may not use this file except in compliance with the License.
11 | * You may obtain a copy of the License at
12 | *
13 | * http://www.apache.org/licenses/LICENSE-2.0
14 | *
15 | * Unless required by applicable law or agreed to in writing, software
16 | * distributed under the License is distributed on an "AS IS" BASIS,
17 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18 | * See the License for the specific language governing permissions and
19 | * limitations under the License.
20 | * #L%
21 | */
22 |
23 | import com.cloudhopper.smpp.SmppConstants;
24 |
25 | public class BindTransmitter extends BaseBind {
26 |
27 | public BindTransmitter() {
28 | super(SmppConstants.CMD_ID_BIND_TRANSMITTER, "bind_transmitter");
29 | }
30 |
31 | @Override
32 | public BindTransmitterResp createResponse() {
33 | BindTransmitterResp resp = new BindTransmitterResp();
34 | resp.setSequenceNumber(this.getSequenceNumber());
35 | return resp;
36 | }
37 |
38 | @Override
39 | public Class getResponseClass() {
40 | return BindTransmitterResp.class;
41 | }
42 |
43 | }
--------------------------------------------------------------------------------
/src/main/java/com/cloudhopper/smpp/pdu/BindTransmitterResp.java:
--------------------------------------------------------------------------------
1 | package com.cloudhopper.smpp.pdu;
2 |
3 | /*
4 | * #%L
5 | * ch-smpp
6 | * %%
7 | * Copyright (C) 2009 - 2015 Cloudhopper by Twitter
8 | * %%
9 | * Licensed under the Apache License, Version 2.0 (the "License");
10 | * you may not use this file except in compliance with the License.
11 | * You may obtain a copy of the License at
12 | *
13 | * http://www.apache.org/licenses/LICENSE-2.0
14 | *
15 | * Unless required by applicable law or agreed to in writing, software
16 | * distributed under the License is distributed on an "AS IS" BASIS,
17 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18 | * See the License for the specific language governing permissions and
19 | * limitations under the License.
20 | * #L%
21 | */
22 |
23 | import com.cloudhopper.smpp.SmppConstants;
24 |
25 | public class BindTransmitterResp extends BaseBindResp {
26 |
27 | public BindTransmitterResp() {
28 | super(SmppConstants.CMD_ID_BIND_TRANSMITTER_RESP, "bind_transmitter_resp");
29 | }
30 |
31 | }
--------------------------------------------------------------------------------
/src/main/java/com/cloudhopper/smpp/pdu/CancelSmResp.java:
--------------------------------------------------------------------------------
1 | package com.cloudhopper.smpp.pdu;
2 |
3 | /*
4 | * #%L
5 | * ch-smpp
6 | * %%
7 | * Copyright (C) 2009 - 2013 Cloudhopper by Twitter
8 | * %%
9 | * Licensed under the Apache License, Version 2.0 (the "License");
10 | * you may not use this file except in compliance with the License.
11 | * You may obtain a copy of the License at
12 | *
13 | * http://www.apache.org/licenses/LICENSE-2.0
14 | *
15 | * Unless required by applicable law or agreed to in writing, software
16 | * distributed under the License is distributed on an "AS IS" BASIS,
17 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18 | * See the License for the specific language governing permissions and
19 | * limitations under the License.
20 | * #L%
21 | */
22 |
23 | import com.cloudhopper.smpp.SmppConstants;
24 | import com.cloudhopper.smpp.type.RecoverablePduException;
25 | import com.cloudhopper.smpp.type.UnrecoverablePduException;
26 | import org.jboss.netty.buffer.ChannelBuffer;
27 |
28 | /**
29 | * SMPP cancel_sm_resp implementation.
30 | *
31 | * @author chris.matthews
32 | */
33 | public class CancelSmResp extends PduResponse {
34 |
35 | public CancelSmResp() {
36 | super(SmppConstants.CMD_ID_CANCEL_SM_RESP, "cancel_sm_resp");
37 | }
38 |
39 | @Override
40 | public void readBody(ChannelBuffer buffer) throws UnrecoverablePduException, RecoverablePduException {
41 | // nothing
42 | }
43 |
44 | @Override
45 | public int calculateByteSizeOfBody() {
46 | return 0;
47 | }
48 |
49 | @Override
50 | public void writeBody(ChannelBuffer buffer) throws UnrecoverablePduException, RecoverablePduException {
51 | // do nothing
52 | }
53 |
54 | @Override
55 | public void appendBodyToString(StringBuilder buffer) {
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/src/main/java/com/cloudhopper/smpp/pdu/DataSm.java:
--------------------------------------------------------------------------------
1 | package com.cloudhopper.smpp.pdu;
2 |
3 | /*
4 | * #%L
5 | * ch-smpp
6 | * %%
7 | * Copyright (C) 2009 - 2015 Cloudhopper by Twitter
8 | * %%
9 | * Licensed under the Apache License, Version 2.0 (the "License");
10 | * you may not use this file except in compliance with the License.
11 | * You may obtain a copy of the License at
12 | *
13 | * http://www.apache.org/licenses/LICENSE-2.0
14 | *
15 | * Unless required by applicable law or agreed to in writing, software
16 | * distributed under the License is distributed on an "AS IS" BASIS,
17 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18 | * See the License for the specific language governing permissions and
19 | * limitations under the License.
20 | * #L%
21 | */
22 |
23 | import com.cloudhopper.smpp.SmppConstants;
24 | import com.cloudhopper.smpp.type.RecoverablePduException;
25 | import com.cloudhopper.smpp.type.UnrecoverablePduException;
26 | import com.cloudhopper.smpp.util.ChannelBufferUtil;
27 | import com.cloudhopper.smpp.util.PduUtil;
28 | import org.jboss.netty.buffer.ChannelBuffer;
29 |
30 | public class DataSm extends BaseSm {
31 |
32 | public DataSm() {
33 | super(SmppConstants.CMD_ID_DATA_SM, "data_sm");
34 | }
35 |
36 | @Override
37 | public DataSmResp createResponse() {
38 | DataSmResp resp = new DataSmResp();
39 | resp.setSequenceNumber(this.getSequenceNumber());
40 | return resp;
41 | }
42 |
43 | @Override
44 | public Class getResponseClass() {
45 | return DataSmResp.class;
46 | }
47 |
48 | @Override
49 | public void readBody(ChannelBuffer buffer) throws UnrecoverablePduException, RecoverablePduException {
50 | this.serviceType = ChannelBufferUtil.readNullTerminatedString(buffer);
51 | this.sourceAddress = ChannelBufferUtil.readAddress(buffer);
52 | this.destAddress = ChannelBufferUtil.readAddress(buffer);
53 | this.esmClass = buffer.readByte();
54 | this.registeredDelivery = buffer.readByte();
55 | this.dataCoding = buffer.readByte();
56 | }
57 |
58 | @Override
59 | public int calculateByteSizeOfBody() {
60 | int bodyLength = 0;
61 | bodyLength += PduUtil.calculateByteSizeOfNullTerminatedString(this.serviceType);
62 | bodyLength += PduUtil.calculateByteSizeOfAddress(this.sourceAddress);
63 | bodyLength += PduUtil.calculateByteSizeOfAddress(this.destAddress);
64 | bodyLength += 3; // esmClass, regDelivery, dataCoding bytes
65 | return bodyLength;
66 | }
67 |
68 | @Override
69 | public void writeBody(ChannelBuffer buffer) throws UnrecoverablePduException, RecoverablePduException {
70 | ChannelBufferUtil.writeNullTerminatedString(buffer, this.serviceType);
71 | ChannelBufferUtil.writeAddress(buffer, this.sourceAddress);
72 | ChannelBufferUtil.writeAddress(buffer, this.destAddress);
73 | buffer.writeByte(this.esmClass);
74 | buffer.writeByte(this.registeredDelivery);
75 | buffer.writeByte(this.dataCoding);
76 | }
77 |
78 | }
--------------------------------------------------------------------------------
/src/main/java/com/cloudhopper/smpp/pdu/DataSmResp.java:
--------------------------------------------------------------------------------
1 | package com.cloudhopper.smpp.pdu;
2 |
3 | /*
4 | * #%L
5 | * ch-smpp
6 | * %%
7 | * Copyright (C) 2009 - 2015 Cloudhopper by Twitter
8 | * %%
9 | * Licensed under the Apache License, Version 2.0 (the "License");
10 | * you may not use this file except in compliance with the License.
11 | * You may obtain a copy of the License at
12 | *
13 | * http://www.apache.org/licenses/LICENSE-2.0
14 | *
15 | * Unless required by applicable law or agreed to in writing, software
16 | * distributed under the License is distributed on an "AS IS" BASIS,
17 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18 | * See the License for the specific language governing permissions and
19 | * limitations under the License.
20 | * #L%
21 | */
22 |
23 | import com.cloudhopper.smpp.SmppConstants;
24 |
25 | public class DataSmResp extends BaseSmResp {
26 |
27 | public DataSmResp() {
28 | super(SmppConstants.CMD_ID_DATA_SM_RESP, "data_sm_resp");
29 | }
30 |
31 | }
--------------------------------------------------------------------------------
/src/main/java/com/cloudhopper/smpp/pdu/DeliverSm.java:
--------------------------------------------------------------------------------
1 | package com.cloudhopper.smpp.pdu;
2 |
3 | /*
4 | * #%L
5 | * ch-smpp
6 | * %%
7 | * Copyright (C) 2009 - 2015 Cloudhopper by Twitter
8 | * %%
9 | * Licensed under the Apache License, Version 2.0 (the "License");
10 | * you may not use this file except in compliance with the License.
11 | * You may obtain a copy of the License at
12 | *
13 | * http://www.apache.org/licenses/LICENSE-2.0
14 | *
15 | * Unless required by applicable law or agreed to in writing, software
16 | * distributed under the License is distributed on an "AS IS" BASIS,
17 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18 | * See the License for the specific language governing permissions and
19 | * limitations under the License.
20 | * #L%
21 | */
22 |
23 | import com.cloudhopper.smpp.SmppConstants;
24 |
25 | public class DeliverSm extends BaseSm {
26 |
27 | public DeliverSm() {
28 | super(SmppConstants.CMD_ID_DELIVER_SM, "deliver_sm");
29 | }
30 |
31 | @Override
32 | public DeliverSmResp createResponse() {
33 | DeliverSmResp resp = new DeliverSmResp();
34 | resp.setSequenceNumber(this.getSequenceNumber());
35 | return resp;
36 | }
37 |
38 | @Override
39 | public Class getResponseClass() {
40 | return DeliverSmResp.class;
41 | }
42 |
43 | }
--------------------------------------------------------------------------------
/src/main/java/com/cloudhopper/smpp/pdu/DeliverSmResp.java:
--------------------------------------------------------------------------------
1 | package com.cloudhopper.smpp.pdu;
2 |
3 | /*
4 | * #%L
5 | * ch-smpp
6 | * %%
7 | * Copyright (C) 2009 - 2015 Cloudhopper by Twitter
8 | * %%
9 | * Licensed under the Apache License, Version 2.0 (the "License");
10 | * you may not use this file except in compliance with the License.
11 | * You may obtain a copy of the License at
12 | *
13 | * http://www.apache.org/licenses/LICENSE-2.0
14 | *
15 | * Unless required by applicable law or agreed to in writing, software
16 | * distributed under the License is distributed on an "AS IS" BASIS,
17 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18 | * See the License for the specific language governing permissions and
19 | * limitations under the License.
20 | * #L%
21 | */
22 |
23 | import com.cloudhopper.smpp.SmppConstants;
24 |
25 | public class DeliverSmResp extends BaseSmResp {
26 |
27 | public DeliverSmResp() {
28 | super(SmppConstants.CMD_ID_DELIVER_SM_RESP, "deliver_sm_resp");
29 | }
30 |
31 | }
--------------------------------------------------------------------------------
/src/main/java/com/cloudhopper/smpp/pdu/EmptyBody.java:
--------------------------------------------------------------------------------
1 | package com.cloudhopper.smpp.pdu;
2 |
3 | /*
4 | * #%L
5 | * ch-smpp
6 | * %%
7 | * Copyright (C) 2009 - 2015 Cloudhopper by Twitter
8 | * %%
9 | * Licensed under the Apache License, Version 2.0 (the "License");
10 | * you may not use this file except in compliance with the License.
11 | * You may obtain a copy of the License at
12 | *
13 | * http://www.apache.org/licenses/LICENSE-2.0
14 | *
15 | * Unless required by applicable law or agreed to in writing, software
16 | * distributed under the License is distributed on an "AS IS" BASIS,
17 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18 | * See the License for the specific language governing permissions and
19 | * limitations under the License.
20 | * #L%
21 | */
22 |
23 | import com.cloudhopper.smpp.type.UnrecoverablePduException;
24 | import com.cloudhopper.smpp.type.RecoverablePduException;
25 | import org.jboss.netty.buffer.ChannelBuffer;
26 |
27 | public abstract class EmptyBody extends PduRequest {
28 |
29 | public EmptyBody(int commandId, String name) {
30 | super(commandId, name);
31 | }
32 |
33 | @Override
34 | public void readBody(ChannelBuffer buffer) throws UnrecoverablePduException, RecoverablePduException {
35 | // no body
36 | }
37 |
38 | @Override
39 | public int calculateByteSizeOfBody() {
40 | return 0; // no body
41 | }
42 |
43 | @Override
44 | public void writeBody(ChannelBuffer buffer) throws UnrecoverablePduException, RecoverablePduException {
45 | /// no body
46 | }
47 |
48 | @Override
49 | public void appendBodyToString(StringBuilder buffer) {
50 | // no body
51 | }
52 |
53 | }
--------------------------------------------------------------------------------
/src/main/java/com/cloudhopper/smpp/pdu/EmptyBodyResp.java:
--------------------------------------------------------------------------------
1 | package com.cloudhopper.smpp.pdu;
2 |
3 | /*
4 | * #%L
5 | * ch-smpp
6 | * %%
7 | * Copyright (C) 2009 - 2015 Cloudhopper by Twitter
8 | * %%
9 | * Licensed under the Apache License, Version 2.0 (the "License");
10 | * you may not use this file except in compliance with the License.
11 | * You may obtain a copy of the License at
12 | *
13 | * http://www.apache.org/licenses/LICENSE-2.0
14 | *
15 | * Unless required by applicable law or agreed to in writing, software
16 | * distributed under the License is distributed on an "AS IS" BASIS,
17 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18 | * See the License for the specific language governing permissions and
19 | * limitations under the License.
20 | * #L%
21 | */
22 |
23 | import com.cloudhopper.smpp.type.UnrecoverablePduException;
24 | import com.cloudhopper.smpp.type.RecoverablePduException;
25 | import org.jboss.netty.buffer.ChannelBuffer;
26 |
27 | public abstract class EmptyBodyResp extends PduResponse {
28 |
29 | public EmptyBodyResp(int commandId, String name) {
30 | super(commandId, name);
31 | }
32 |
33 | @Override
34 | public void readBody(ChannelBuffer buffer) throws UnrecoverablePduException, RecoverablePduException {
35 | // no body
36 | }
37 |
38 | @Override
39 | public int calculateByteSizeOfBody() {
40 | return 0; // no body
41 | }
42 |
43 | @Override
44 | public void writeBody(ChannelBuffer buffer) throws UnrecoverablePduException, RecoverablePduException {
45 | // no body
46 | }
47 |
48 | @Override
49 | public void appendBodyToString(StringBuilder buffer) {
50 | // no body
51 | }
52 |
53 | }
--------------------------------------------------------------------------------
/src/main/java/com/cloudhopper/smpp/pdu/EnquireLink.java:
--------------------------------------------------------------------------------
1 | package com.cloudhopper.smpp.pdu;
2 |
3 | /*
4 | * #%L
5 | * ch-smpp
6 | * %%
7 | * Copyright (C) 2009 - 2015 Cloudhopper by Twitter
8 | * %%
9 | * Licensed under the Apache License, Version 2.0 (the "License");
10 | * you may not use this file except in compliance with the License.
11 | * You may obtain a copy of the License at
12 | *
13 | * http://www.apache.org/licenses/LICENSE-2.0
14 | *
15 | * Unless required by applicable law or agreed to in writing, software
16 | * distributed under the License is distributed on an "AS IS" BASIS,
17 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18 | * See the License for the specific language governing permissions and
19 | * limitations under the License.
20 | * #L%
21 | */
22 |
23 | import com.cloudhopper.smpp.SmppConstants;
24 |
25 | public class EnquireLink extends EmptyBody {
26 |
27 | public EnquireLink() {
28 | super(SmppConstants.CMD_ID_ENQUIRE_LINK, "enquire_link");
29 | }
30 |
31 | @Override
32 | public EnquireLinkResp createResponse() {
33 | EnquireLinkResp resp = new EnquireLinkResp();
34 | resp.setSequenceNumber(this.getSequenceNumber());
35 | return resp;
36 | }
37 |
38 | @Override
39 | public Class getResponseClass() {
40 | return EnquireLinkResp.class;
41 | }
42 |
43 | }
--------------------------------------------------------------------------------
/src/main/java/com/cloudhopper/smpp/pdu/EnquireLinkResp.java:
--------------------------------------------------------------------------------
1 | package com.cloudhopper.smpp.pdu;
2 |
3 | /*
4 | * #%L
5 | * ch-smpp
6 | * %%
7 | * Copyright (C) 2009 - 2015 Cloudhopper by Twitter
8 | * %%
9 | * Licensed under the Apache License, Version 2.0 (the "License");
10 | * you may not use this file except in compliance with the License.
11 | * You may obtain a copy of the License at
12 | *
13 | * http://www.apache.org/licenses/LICENSE-2.0
14 | *
15 | * Unless required by applicable law or agreed to in writing, software
16 | * distributed under the License is distributed on an "AS IS" BASIS,
17 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18 | * See the License for the specific language governing permissions and
19 | * limitations under the License.
20 | * #L%
21 | */
22 |
23 | import com.cloudhopper.smpp.SmppConstants;
24 |
25 | public class EnquireLinkResp extends EmptyBodyResp {
26 |
27 | public EnquireLinkResp() {
28 | super(SmppConstants.CMD_ID_ENQUIRE_LINK_RESP, "enquire_link_resp");
29 | }
30 |
31 | }
--------------------------------------------------------------------------------
/src/main/java/com/cloudhopper/smpp/pdu/GenericNack.java:
--------------------------------------------------------------------------------
1 | package com.cloudhopper.smpp.pdu;
2 |
3 | /*
4 | * #%L
5 | * ch-smpp
6 | * %%
7 | * Copyright (C) 2009 - 2015 Cloudhopper by Twitter
8 | * %%
9 | * Licensed under the Apache License, Version 2.0 (the "License");
10 | * you may not use this file except in compliance with the License.
11 | * You may obtain a copy of the License at
12 | *
13 | * http://www.apache.org/licenses/LICENSE-2.0
14 | *
15 | * Unless required by applicable law or agreed to in writing, software
16 | * distributed under the License is distributed on an "AS IS" BASIS,
17 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18 | * See the License for the specific language governing permissions and
19 | * limitations under the License.
20 | * #L%
21 | */
22 |
23 | import com.cloudhopper.smpp.type.UnrecoverablePduException;
24 | import com.cloudhopper.smpp.type.RecoverablePduException;
25 | import com.cloudhopper.smpp.SmppConstants;
26 | import org.jboss.netty.buffer.ChannelBuffer;
27 |
28 | public class GenericNack extends PduResponse {
29 |
30 | public GenericNack() {
31 | super(SmppConstants.CMD_ID_GENERIC_NACK, "generic_nack");
32 | }
33 |
34 | @Override
35 | public void readBody(ChannelBuffer buffer) throws UnrecoverablePduException, RecoverablePduException {
36 | // no body
37 | }
38 |
39 | @Override
40 | public int calculateByteSizeOfBody() {
41 | return 0; // no body
42 | }
43 |
44 | @Override
45 | public void writeBody(ChannelBuffer buffer) throws UnrecoverablePduException, RecoverablePduException {
46 | /// no body
47 | }
48 |
49 | @Override
50 | public void appendBodyToString(StringBuilder buffer) {
51 | // no body
52 | }
53 |
54 | }
--------------------------------------------------------------------------------
/src/main/java/com/cloudhopper/smpp/pdu/PartialPdu.java:
--------------------------------------------------------------------------------
1 | package com.cloudhopper.smpp.pdu;
2 |
3 | /*
4 | * #%L
5 | * ch-smpp
6 | * %%
7 | * Copyright (C) 2009 - 2015 Cloudhopper by Twitter
8 | * %%
9 | * Licensed under the Apache License, Version 2.0 (the "License");
10 | * you may not use this file except in compliance with the License.
11 | * You may obtain a copy of the License at
12 | *
13 | * http://www.apache.org/licenses/LICENSE-2.0
14 | *
15 | * Unless required by applicable law or agreed to in writing, software
16 | * distributed under the License is distributed on an "AS IS" BASIS,
17 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18 | * See the License for the specific language governing permissions and
19 | * limitations under the License.
20 | * #L%
21 | */
22 |
23 | public class PartialPdu extends EmptyBody {
24 |
25 | public PartialPdu(int commandId) {
26 | super(commandId, "partial_pdu");
27 | }
28 |
29 | @Override
30 | public GenericNack createResponse() {
31 | GenericNack resp = new GenericNack();
32 | resp.setSequenceNumber(this.getSequenceNumber());
33 | return resp;
34 | }
35 |
36 | @Override
37 | public Class getResponseClass() {
38 | return GenericNack.class;
39 | }
40 |
41 | }
--------------------------------------------------------------------------------
/src/main/java/com/cloudhopper/smpp/pdu/PartialPduResp.java:
--------------------------------------------------------------------------------
1 | package com.cloudhopper.smpp.pdu;
2 |
3 | /*
4 | * #%L
5 | * ch-smpp
6 | * %%
7 | * Copyright (C) 2009 - 2015 Cloudhopper by Twitter
8 | * %%
9 | * Licensed under the Apache License, Version 2.0 (the "License");
10 | * you may not use this file except in compliance with the License.
11 | * You may obtain a copy of the License at
12 | *
13 | * http://www.apache.org/licenses/LICENSE-2.0
14 | *
15 | * Unless required by applicable law or agreed to in writing, software
16 | * distributed under the License is distributed on an "AS IS" BASIS,
17 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18 | * See the License for the specific language governing permissions and
19 | * limitations under the License.
20 | * #L%
21 | */
22 |
23 | public class PartialPduResp extends EmptyBodyResp {
24 |
25 | public PartialPduResp(int commandId) {
26 | super(commandId, "partial_pdu_resp");
27 | }
28 |
29 | }
--------------------------------------------------------------------------------
/src/main/java/com/cloudhopper/smpp/pdu/PduRequest.java:
--------------------------------------------------------------------------------
1 | package com.cloudhopper.smpp.pdu;
2 |
3 | /*
4 | * #%L
5 | * ch-smpp
6 | * %%
7 | * Copyright (C) 2009 - 2015 Cloudhopper by Twitter
8 | * %%
9 | * Licensed under the Apache License, Version 2.0 (the "License");
10 | * you may not use this file except in compliance with the License.
11 | * You may obtain a copy of the License at
12 | *
13 | * http://www.apache.org/licenses/LICENSE-2.0
14 | *
15 | * Unless required by applicable law or agreed to in writing, software
16 | * distributed under the License is distributed on an "AS IS" BASIS,
17 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18 | * See the License for the specific language governing permissions and
19 | * limitations under the License.
20 | * #L%
21 | */
22 |
23 | public abstract class PduRequest extends Pdu {
24 |
25 | public PduRequest(int commandId, String name) {
26 | super(commandId, name, true);
27 | }
28 |
29 | abstract public R createResponse();
30 |
31 | abstract public Class getResponseClass();
32 |
33 | public GenericNack createGenericNack(int commandStatus) {
34 | GenericNack nack = new GenericNack();
35 | nack.setCommandStatus(commandStatus);
36 | nack.setSequenceNumber(this.getSequenceNumber());
37 | return nack;
38 | }
39 |
40 | }
--------------------------------------------------------------------------------
/src/main/java/com/cloudhopper/smpp/pdu/PduResponse.java:
--------------------------------------------------------------------------------
1 | package com.cloudhopper.smpp.pdu;
2 |
3 | /*
4 | * #%L
5 | * ch-smpp
6 | * %%
7 | * Copyright (C) 2009 - 2015 Cloudhopper by Twitter
8 | * %%
9 | * Licensed under the Apache License, Version 2.0 (the "License");
10 | * you may not use this file except in compliance with the License.
11 | * You may obtain a copy of the License at
12 | *
13 | * http://www.apache.org/licenses/LICENSE-2.0
14 | *
15 | * Unless required by applicable law or agreed to in writing, software
16 | * distributed under the License is distributed on an "AS IS" BASIS,
17 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18 | * See the License for the specific language governing permissions and
19 | * limitations under the License.
20 | * #L%
21 | */
22 |
23 | public abstract class PduResponse extends Pdu {
24 |
25 | private String resultMessage;
26 |
27 | public PduResponse(int commandId, String name) {
28 | super(commandId, name, false);
29 | }
30 |
31 | public void setResultMessage(String value) {
32 | this.resultMessage = value;
33 | }
34 |
35 | public String getResultMessage() {
36 | return this.resultMessage;
37 | }
38 |
39 | }
--------------------------------------------------------------------------------
/src/main/java/com/cloudhopper/smpp/pdu/QuerySm.java:
--------------------------------------------------------------------------------
1 | package com.cloudhopper.smpp.pdu;
2 |
3 | /*
4 | * #%L
5 | * ch-smpp
6 | * %%
7 | * Copyright (C) 2009 - 2013 Cloudhopper by Twitter
8 | * %%
9 | * Licensed under the Apache License, Version 2.0 (the "License");
10 | * you may not use this file except in compliance with the License.
11 | * You may obtain a copy of the License at
12 | *
13 | * http://www.apache.org/licenses/LICENSE-2.0
14 | *
15 | * Unless required by applicable law or agreed to in writing, software
16 | * distributed under the License is distributed on an "AS IS" BASIS,
17 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18 | * See the License for the specific language governing permissions and
19 | * limitations under the License.
20 | * #L%
21 | */
22 |
23 | import com.cloudhopper.commons.util.StringUtil;
24 | import com.cloudhopper.smpp.SmppConstants;
25 | import com.cloudhopper.smpp.type.Address;
26 | import com.cloudhopper.smpp.type.RecoverablePduException;
27 | import com.cloudhopper.smpp.type.UnrecoverablePduException;
28 | import com.cloudhopper.smpp.util.ChannelBufferUtil;
29 | import com.cloudhopper.smpp.util.PduUtil;
30 | import org.jboss.netty.buffer.ChannelBuffer;
31 |
32 | /**
33 | * SMPP query_sm implementation.
34 | *
35 | * @author chris.matthews
36 | */
37 | public class QuerySm extends PduRequest {
38 |
39 | private String messageId;
40 | private Address sourceAddress;
41 |
42 | public QuerySm() {
43 | super(SmppConstants.CMD_ID_QUERY_SM, "query_sm");
44 | }
45 |
46 | public String getMessageId() {
47 | return this.messageId;
48 | }
49 |
50 | public void setMessageId(String value) {
51 | this.messageId = value;
52 | }
53 |
54 | public Address getSourceAddress() {
55 | return this.sourceAddress;
56 | }
57 |
58 | public void setSourceAddress(Address value) {
59 | this.sourceAddress = value;
60 | }
61 |
62 |
63 | @Override
64 | public void readBody(ChannelBuffer buffer) throws UnrecoverablePduException, RecoverablePduException {
65 | this.messageId = ChannelBufferUtil.readNullTerminatedString(buffer);
66 | this.sourceAddress = ChannelBufferUtil.readAddress(buffer);
67 | }
68 |
69 | @Override
70 | public int calculateByteSizeOfBody() {
71 | int bodyLength = 0;
72 | bodyLength += PduUtil.calculateByteSizeOfNullTerminatedString(this.messageId);
73 | bodyLength += PduUtil.calculateByteSizeOfAddress(this.sourceAddress);
74 | return bodyLength;
75 | }
76 |
77 | @Override
78 | public void writeBody(ChannelBuffer buffer) throws UnrecoverablePduException, RecoverablePduException {
79 | ChannelBufferUtil.writeNullTerminatedString(buffer, this.messageId);
80 | ChannelBufferUtil.writeAddress(buffer, this.sourceAddress);
81 | }
82 |
83 | @Override
84 | public void appendBodyToString(StringBuilder buffer) {
85 | buffer.append("(messageId [");
86 | buffer.append(StringUtil.toStringWithNullAsEmpty(this.messageId));
87 | buffer.append("] sourceAddr [");
88 | buffer.append(StringUtil.toStringWithNullAsEmpty(this.sourceAddress));
89 | buffer.append("])");
90 |
91 | }
92 |
93 | @Override
94 | public QuerySmResp createResponse() {
95 | QuerySmResp resp = new QuerySmResp();
96 | resp.setSequenceNumber(this.getSequenceNumber());
97 | return resp;
98 | }
99 |
100 | @Override
101 | public Class getResponseClass() {
102 | return QuerySmResp.class;
103 | }
104 |
105 | }
106 |
--------------------------------------------------------------------------------
/src/main/java/com/cloudhopper/smpp/pdu/ReplaceSmResp.java:
--------------------------------------------------------------------------------
1 | package com.cloudhopper.smpp.pdu;
2 |
3 | /*
4 | * #%L
5 | * ch-smpp
6 | * %%
7 | * Copyright (C) 2009 - 2015 Cloudhopper by Twitter
8 | * %%
9 | * Licensed under the Apache License, Version 2.0 (the "License");
10 | * you may not use this file except in compliance with the License.
11 | * You may obtain a copy of the License at
12 | *
13 | * http://www.apache.org/licenses/LICENSE-2.0
14 | *
15 | * Unless required by applicable law or agreed to in writing, software
16 | * distributed under the License is distributed on an "AS IS" BASIS,
17 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18 | * See the License for the specific language governing permissions and
19 | * limitations under the License.
20 | * #L%
21 | */
22 |
23 | import org.jboss.netty.buffer.ChannelBuffer;
24 |
25 | import com.cloudhopper.smpp.SmppConstants;
26 | import com.cloudhopper.smpp.type.RecoverablePduException;
27 | import com.cloudhopper.smpp.type.UnrecoverablePduException;
28 |
29 | public class ReplaceSmResp extends PduResponse {
30 |
31 | public ReplaceSmResp() {
32 | super(SmppConstants.CMD_ID_REPLACE_SM_RESP, "replace_sm_resp");
33 | }
34 |
35 | @Override
36 | public void readBody(ChannelBuffer buffer) throws UnrecoverablePduException, RecoverablePduException {
37 | // nothing
38 | }
39 |
40 | @Override
41 | public int calculateByteSizeOfBody() {
42 | return 0;
43 | }
44 |
45 | @Override
46 | public void writeBody(ChannelBuffer buffer) throws UnrecoverablePduException, RecoverablePduException {
47 | // do nothing
48 | }
49 |
50 | @Override
51 | public void appendBodyToString(StringBuilder buffer) {
52 | }
53 |
54 | }
--------------------------------------------------------------------------------
/src/main/java/com/cloudhopper/smpp/pdu/SubmitMultiResp.java:
--------------------------------------------------------------------------------
1 | /**
2 | *
3 | */
4 | package com.cloudhopper.smpp.pdu;
5 |
6 | /*
7 | * #%L
8 | * ch-smpp
9 | * %%
10 | * Copyright (C) 2009 - 2013 Cloudhopper by Twitter
11 | * %%
12 | * Licensed under the Apache License, Version 2.0 (the "License");
13 | * you may not use this file except in compliance with the License.
14 | * You may obtain a copy of the License at
15 | *
16 | * http://www.apache.org/licenses/LICENSE-2.0
17 | *
18 | * Unless required by applicable law or agreed to in writing, software
19 | * distributed under the License is distributed on an "AS IS" BASIS,
20 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
21 | * See the License for the specific language governing permissions and
22 | * limitations under the License.
23 | * #L%
24 | */
25 |
26 | import java.util.ArrayList;
27 | import java.util.List;
28 |
29 | import org.jboss.netty.buffer.ChannelBuffer;
30 |
31 | import com.cloudhopper.smpp.SmppConstants;
32 | import com.cloudhopper.smpp.type.Address;
33 | import com.cloudhopper.smpp.type.RecoverablePduException;
34 | import com.cloudhopper.smpp.type.SmppInvalidArgumentException;
35 | import com.cloudhopper.smpp.type.UnrecoverablePduException;
36 | import com.cloudhopper.smpp.type.UnsucessfulSME;
37 | import com.cloudhopper.smpp.util.ChannelBufferUtil;
38 | import com.cloudhopper.smpp.util.PduUtil;
39 |
40 | /**
41 | * @author Amit Bhayani
42 | *
43 | */
44 | public class SubmitMultiResp extends BaseSmResp {
45 |
46 | private int numberOfUnsucessfulDest;
47 | private List unsucessfulSmes = new ArrayList();
48 |
49 | /**
50 | * @param commandId
51 | * @param name
52 | */
53 | public SubmitMultiResp() {
54 | super(SmppConstants.CMD_ID_SUBMIT_MULTI_RESP, "submit_multi_resp");
55 | }
56 |
57 | public void addUnsucessfulSME(UnsucessfulSME unsucessfulSME)
58 | throws SmppInvalidArgumentException {
59 | this.numberOfUnsucessfulDest++;
60 | this.unsucessfulSmes.add(unsucessfulSME);
61 | }
62 |
63 | public int getNumberOfUnsucessfulDest() {
64 | return numberOfUnsucessfulDest;
65 | }
66 |
67 | public List getUnsucessfulSmes() {
68 | return unsucessfulSmes;
69 | }
70 |
71 | @Override
72 | public void readBody(ChannelBuffer buffer)
73 | throws UnrecoverablePduException, RecoverablePduException {
74 | super.readBody(buffer);
75 |
76 | this.numberOfUnsucessfulDest = buffer.readByte() & 0xFF;
77 |
78 | for (int count = 0; count < this.numberOfUnsucessfulDest; count++) {
79 | Address address = ChannelBufferUtil.readAddress(buffer);
80 | int errorStatusCode = buffer.readInt();
81 |
82 | this.unsucessfulSmes.add(new UnsucessfulSME(errorStatusCode,
83 | address));
84 |
85 | }
86 | }
87 |
88 | @Override
89 | public int calculateByteSizeOfBody() {
90 | int bodyLength = 0;
91 | bodyLength = super.calculateByteSizeOfBody();
92 |
93 | bodyLength += 1; // no_unsuccess
94 |
95 | for (int count = 0; count < this.numberOfUnsucessfulDest; count++) {
96 | UnsucessfulSME unsucessfulSME = this.unsucessfulSmes.get(count);
97 | bodyLength += PduUtil.calculateByteSizeOfAddress(unsucessfulSME
98 | .getAddress());
99 | bodyLength += 4; // error_status_code
100 | }
101 |
102 | return bodyLength;
103 | }
104 |
105 | @Override
106 | public void writeBody(ChannelBuffer buffer)
107 | throws UnrecoverablePduException, RecoverablePduException {
108 | super.writeBody(buffer);
109 |
110 | buffer.writeByte(this.numberOfUnsucessfulDest);
111 |
112 | for (int count = 0; count < this.numberOfUnsucessfulDest; count++) {
113 | UnsucessfulSME unsucessfulSME = this.unsucessfulSmes.get(count);
114 | ChannelBufferUtil.writeAddress(buffer, unsucessfulSME.getAddress());
115 | buffer.writeInt(unsucessfulSME.getErrorStatusCode());
116 | }
117 | }
118 |
119 | }
120 |
--------------------------------------------------------------------------------
/src/main/java/com/cloudhopper/smpp/pdu/SubmitSm.java:
--------------------------------------------------------------------------------
1 | package com.cloudhopper.smpp.pdu;
2 |
3 | /*
4 | * #%L
5 | * ch-smpp
6 | * %%
7 | * Copyright (C) 2009 - 2015 Cloudhopper by Twitter
8 | * %%
9 | * Licensed under the Apache License, Version 2.0 (the "License");
10 | * you may not use this file except in compliance with the License.
11 | * You may obtain a copy of the License at
12 | *
13 | * http://www.apache.org/licenses/LICENSE-2.0
14 | *
15 | * Unless required by applicable law or agreed to in writing, software
16 | * distributed under the License is distributed on an "AS IS" BASIS,
17 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18 | * See the License for the specific language governing permissions and
19 | * limitations under the License.
20 | * #L%
21 | */
22 |
23 | import com.cloudhopper.smpp.SmppConstants;
24 |
25 | public class SubmitSm extends BaseSm {
26 |
27 | public SubmitSm() {
28 | super(SmppConstants.CMD_ID_SUBMIT_SM, "submit_sm");
29 | }
30 |
31 | @Override
32 | public SubmitSmResp createResponse() {
33 | SubmitSmResp resp = new SubmitSmResp();
34 | resp.setSequenceNumber(this.getSequenceNumber());
35 | return resp;
36 | }
37 |
38 | @Override
39 | public Class getResponseClass() {
40 | return SubmitSmResp.class;
41 | }
42 |
43 | }
--------------------------------------------------------------------------------
/src/main/java/com/cloudhopper/smpp/pdu/SubmitSmResp.java:
--------------------------------------------------------------------------------
1 | package com.cloudhopper.smpp.pdu;
2 |
3 | /*
4 | * #%L
5 | * ch-smpp
6 | * %%
7 | * Copyright (C) 2009 - 2015 Cloudhopper by Twitter
8 | * %%
9 | * Licensed under the Apache License, Version 2.0 (the "License");
10 | * you may not use this file except in compliance with the License.
11 | * You may obtain a copy of the License at
12 | *
13 | * http://www.apache.org/licenses/LICENSE-2.0
14 | *
15 | * Unless required by applicable law or agreed to in writing, software
16 | * distributed under the License is distributed on an "AS IS" BASIS,
17 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18 | * See the License for the specific language governing permissions and
19 | * limitations under the License.
20 | * #L%
21 | */
22 |
23 | import com.cloudhopper.smpp.SmppConstants;
24 |
25 | public class SubmitSmResp extends BaseSmResp {
26 |
27 | public SubmitSmResp() {
28 | super(SmppConstants.CMD_ID_SUBMIT_SM_RESP, "submit_sm_resp");
29 | }
30 |
31 | }
--------------------------------------------------------------------------------
/src/main/java/com/cloudhopper/smpp/pdu/Unbind.java:
--------------------------------------------------------------------------------
1 | package com.cloudhopper.smpp.pdu;
2 |
3 | /*
4 | * #%L
5 | * ch-smpp
6 | * %%
7 | * Copyright (C) 2009 - 2015 Cloudhopper by Twitter
8 | * %%
9 | * Licensed under the Apache License, Version 2.0 (the "License");
10 | * you may not use this file except in compliance with the License.
11 | * You may obtain a copy of the License at
12 | *
13 | * http://www.apache.org/licenses/LICENSE-2.0
14 | *
15 | * Unless required by applicable law or agreed to in writing, software
16 | * distributed under the License is distributed on an "AS IS" BASIS,
17 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18 | * See the License for the specific language governing permissions and
19 | * limitations under the License.
20 | * #L%
21 | */
22 |
23 | import com.cloudhopper.smpp.SmppConstants;
24 |
25 | public class Unbind extends EmptyBody {
26 |
27 | public Unbind() {
28 | super(SmppConstants.CMD_ID_UNBIND, "unbind");
29 | }
30 |
31 | @Override
32 | public UnbindResp createResponse() {
33 | UnbindResp resp = new UnbindResp();
34 | resp.setSequenceNumber(this.getSequenceNumber());
35 | return resp;
36 | }
37 |
38 | @Override
39 | public Class getResponseClass() {
40 | return UnbindResp.class;
41 | }
42 |
43 | }
--------------------------------------------------------------------------------
/src/main/java/com/cloudhopper/smpp/pdu/UnbindResp.java:
--------------------------------------------------------------------------------
1 | package com.cloudhopper.smpp.pdu;
2 |
3 | /*
4 | * #%L
5 | * ch-smpp
6 | * %%
7 | * Copyright (C) 2009 - 2015 Cloudhopper by Twitter
8 | * %%
9 | * Licensed under the Apache License, Version 2.0 (the "License");
10 | * you may not use this file except in compliance with the License.
11 | * You may obtain a copy of the License at
12 | *
13 | * http://www.apache.org/licenses/LICENSE-2.0
14 | *
15 | * Unless required by applicable law or agreed to in writing, software
16 | * distributed under the License is distributed on an "AS IS" BASIS,
17 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18 | * See the License for the specific language governing permissions and
19 | * limitations under the License.
20 | * #L%
21 | */
22 |
23 | import com.cloudhopper.smpp.type.UnrecoverablePduException;
24 | import com.cloudhopper.smpp.type.RecoverablePduException;
25 | import com.cloudhopper.smpp.SmppConstants;
26 | import org.jboss.netty.buffer.ChannelBuffer;
27 |
28 | public class UnbindResp extends EmptyBodyResp {
29 |
30 | public UnbindResp() {
31 | super(SmppConstants.CMD_ID_UNBIND_RESP, "unbind_resp");
32 | }
33 |
34 | }
--------------------------------------------------------------------------------
/src/main/java/com/cloudhopper/smpp/simulator/SmppSimulatorBindProcessor.java:
--------------------------------------------------------------------------------
1 | package com.cloudhopper.smpp.simulator;
2 |
3 | /*
4 | * #%L
5 | * ch-smpp
6 | * %%
7 | * Copyright (C) 2009 - 2015 Cloudhopper by Twitter
8 | * %%
9 | * Licensed under the Apache License, Version 2.0 (the "License");
10 | * you may not use this file except in compliance with the License.
11 | * You may obtain a copy of the License at
12 | *
13 | * http://www.apache.org/licenses/LICENSE-2.0
14 | *
15 | * Unless required by applicable law or agreed to in writing, software
16 | * distributed under the License is distributed on an "AS IS" BASIS,
17 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18 | * See the License for the specific language governing permissions and
19 | * limitations under the License.
20 | * #L%
21 | */
22 |
23 | import com.cloudhopper.smpp.SmppConstants;
24 | import com.cloudhopper.smpp.pdu.BaseBind;
25 | import com.cloudhopper.smpp.pdu.BaseBindResp;
26 | import com.cloudhopper.smpp.pdu.Pdu;
27 | import com.cloudhopper.smpp.pdu.PduRequest;
28 | import org.jboss.netty.channel.Channel;
29 |
30 | /**
31 | *
32 | * @author joelauer (twitter: @jjlauer or http://twitter.com/jjlauer)
33 | */
34 | public class SmppSimulatorBindProcessor implements SmppSimulatorPduProcessor {
35 |
36 | private String systemId;
37 | private String password;
38 |
39 | public SmppSimulatorBindProcessor(String systemId, String password) {
40 | this.systemId = systemId;
41 | this.password = password;
42 | }
43 |
44 | @Override
45 | public boolean process(SmppSimulatorSessionHandler session, Channel channel, Pdu pdu) throws Exception {
46 | // anything other than a bind is super bad!
47 | if (!(pdu instanceof BaseBind)) {
48 | if (pdu instanceof PduRequest) {
49 | session.addPduToWriteOnNextPduReceived(((PduRequest)pdu).createGenericNack(SmppConstants.STATUS_INVBNDSTS));
50 | return true;
51 | } else {
52 | //logger.error("PDU response received, but not bound");
53 | channel.close();
54 | return true;
55 | }
56 | }
57 |
58 | BaseBind bind = (BaseBind)pdu;
59 | BaseBindResp bindResp = (BaseBindResp)bind.createResponse();
60 |
61 | if (!bind.getSystemId().equals(systemId)) {
62 | bindResp.setCommandStatus(SmppConstants.STATUS_INVSYSID);
63 | } else if (!bind.getPassword().equals(password)) {
64 | bindResp.setCommandStatus(SmppConstants.STATUS_INVPASWD);
65 | }
66 |
67 | session.addPduToWriteOnNextPduReceived(bindResp);
68 | return true;
69 | }
70 |
71 | }
72 |
--------------------------------------------------------------------------------
/src/main/java/com/cloudhopper/smpp/simulator/SmppSimulatorPduProcessor.java:
--------------------------------------------------------------------------------
1 | package com.cloudhopper.smpp.simulator;
2 |
3 | /*
4 | * #%L
5 | * ch-smpp
6 | * %%
7 | * Copyright (C) 2009 - 2015 Cloudhopper by Twitter
8 | * %%
9 | * Licensed under the Apache License, Version 2.0 (the "License");
10 | * you may not use this file except in compliance with the License.
11 | * You may obtain a copy of the License at
12 | *
13 | * http://www.apache.org/licenses/LICENSE-2.0
14 | *
15 | * Unless required by applicable law or agreed to in writing, software
16 | * distributed under the License is distributed on an "AS IS" BASIS,
17 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18 | * See the License for the specific language governing permissions and
19 | * limitations under the License.
20 | * #L%
21 | */
22 |
23 | import com.cloudhopper.smpp.pdu.Pdu;
24 | import org.jboss.netty.channel.Channel;
25 |
26 | /**
27 | *
28 | * @author joelauer (twitter: @jjlauer or http://twitter.com/jjlauer)
29 | */
30 | public interface SmppSimulatorPduProcessor {
31 |
32 | public boolean process(SmppSimulatorSessionHandler session, Channel channel, Pdu pdu) throws Exception;
33 |
34 | }
35 |
--------------------------------------------------------------------------------
/src/main/java/com/cloudhopper/smpp/tlv/TlvConvertException.java:
--------------------------------------------------------------------------------
1 | package com.cloudhopper.smpp.tlv;
2 |
3 | /*
4 | * #%L
5 | * ch-smpp
6 | * %%
7 | * Copyright (C) 2009 - 2015 Cloudhopper by Twitter
8 | * %%
9 | * Licensed under the Apache License, Version 2.0 (the "License");
10 | * you may not use this file except in compliance with the License.
11 | * You may obtain a copy of the License at
12 | *
13 | * http://www.apache.org/licenses/LICENSE-2.0
14 | *
15 | * Unless required by applicable law or agreed to in writing, software
16 | * distributed under the License is distributed on an "AS IS" BASIS,
17 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18 | * See the License for the specific language governing permissions and
19 | * limitations under the License.
20 | * #L%
21 | */
22 |
23 | import com.cloudhopper.smpp.type.RecoverablePduException;
24 |
25 | /**
26 | * Thrown when attempting to cast a TLV value into a different type such as a
27 | * byte, string, etc.
28 | *
29 | * @author joelauer (twitter: @jjlauer or http://twitter.com/jjlauer)
30 | */
31 | public class TlvConvertException extends RecoverablePduException {
32 | static final long serialVersionUID = 1L;
33 |
34 | public TlvConvertException(String msg) {
35 | super(msg);
36 | }
37 |
38 | public TlvConvertException(String typeName, String extraMsg) {
39 | super("Unable to cast TLV value into " + typeName + ": " + extraMsg);
40 | }
41 |
42 | public TlvConvertException(String msg, Throwable t) {
43 | super(msg, t);
44 | }
45 | }
--------------------------------------------------------------------------------
/src/main/java/com/cloudhopper/smpp/transcoder/DefaultPduTranscoderContext.java:
--------------------------------------------------------------------------------
1 | package com.cloudhopper.smpp.transcoder;
2 |
3 | /*
4 | * #%L
5 | * ch-smpp
6 | * %%
7 | * Copyright (C) 2009 - 2015 Cloudhopper by Twitter
8 | * %%
9 | * Licensed under the Apache License, Version 2.0 (the "License");
10 | * you may not use this file except in compliance with the License.
11 | * You may obtain a copy of the License at
12 | *
13 | * http://www.apache.org/licenses/LICENSE-2.0
14 | *
15 | * Unless required by applicable law or agreed to in writing, software
16 | * distributed under the License is distributed on an "AS IS" BASIS,
17 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18 | * See the License for the specific language governing permissions and
19 | * limitations under the License.
20 | * #L%
21 | */
22 |
23 | import com.cloudhopper.smpp.SmppConstants;
24 |
25 | /**
26 | * Provides a default context for a PduTranscoder by looking everything up
27 | * using SMPP constants or default settings. An "override" context can be
28 | * supplied in the constructor. By default, this context will then attempt
29 | * to call the overridden context and any null value returned will then be
30 | * looked up using standard rules.
31 | *
32 | * @author joelauer (twitter: @jjlauer or http://twitter.com/jjlauer)
33 | */
34 | public class DefaultPduTranscoderContext implements PduTranscoderContext {
35 |
36 | private final PduTranscoderContext overrideContext;
37 |
38 | public DefaultPduTranscoderContext() {
39 | this(null);
40 | }
41 |
42 | public DefaultPduTranscoderContext(PduTranscoderContext overrideContext) {
43 | this.overrideContext = overrideContext;
44 | }
45 |
46 | @Override
47 | public String lookupResultMessage(int commandStatus) {
48 | String resultMessage = null;
49 | if (overrideContext != null) {
50 | resultMessage = overrideContext.lookupResultMessage(commandStatus);
51 | }
52 | if (resultMessage == null) {
53 | resultMessage = SmppConstants.STATUS_MESSAGE_MAP.get(new Integer(commandStatus));
54 | }
55 | return resultMessage;
56 | }
57 |
58 | @Override
59 | public String lookupTlvTagName(short tag) {
60 | String tagName = null;
61 | if (overrideContext != null) {
62 | tagName = overrideContext.lookupTlvTagName(tag);
63 | }
64 | if (tagName == null) {
65 | tagName = SmppConstants.TAG_NAME_MAP.get(new Short(tag));
66 | }
67 | return tagName;
68 | }
69 |
70 | }
--------------------------------------------------------------------------------
/src/main/java/com/cloudhopper/smpp/transcoder/PduTranscoder.java:
--------------------------------------------------------------------------------
1 | package com.cloudhopper.smpp.transcoder;
2 |
3 | /*
4 | * #%L
5 | * ch-smpp
6 | * %%
7 | * Copyright (C) 2009 - 2015 Cloudhopper by Twitter
8 | * %%
9 | * Licensed under the Apache License, Version 2.0 (the "License");
10 | * you may not use this file except in compliance with the License.
11 | * You may obtain a copy of the License at
12 | *
13 | * http://www.apache.org/licenses/LICENSE-2.0
14 | *
15 | * Unless required by applicable law or agreed to in writing, software
16 | * distributed under the License is distributed on an "AS IS" BASIS,
17 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18 | * See the License for the specific language governing permissions and
19 | * limitations under the License.
20 | * #L%
21 | */
22 |
23 | import com.cloudhopper.smpp.pdu.Pdu;
24 | import com.cloudhopper.smpp.type.UnrecoverablePduException;
25 | import com.cloudhopper.smpp.type.RecoverablePduException;
26 | import org.jboss.netty.buffer.ChannelBuffer;
27 |
28 | /**
29 | * Interface for encoding/decoding PDUs to/from ChannelBuffers.
30 | *
31 | * @author joelauer (twitter: @jjlauer or http://twitter.com/jjlauer)
32 | */
33 | public interface PduTranscoder {
34 |
35 | /**
36 | * Encodes a PDU into a new ChannelBuffer.
37 | * @param pdu The PDU to convert into a buffer
38 | * @return The new ChannelBuffer ready to send on a Channel
39 | * @throws UnrecoverablePduEncodingException Thrown if there is an unrecoverable
40 | * error while encoding the buffer. Recommended action is to rebind
41 | * the session.
42 | * @throws RecoverablePduEncodingException Thrown if there is recoverable
43 | * error while encoding the buffer. A good example is an optional parameter
44 | * that is invalid or a terminating null byte wasn't found.
45 | */
46 | public ChannelBuffer encode(Pdu pdu) throws UnrecoverablePduException, RecoverablePduException;
47 |
48 | /**
49 | * Decodes a ChannelBuffer into a new PDU.
50 | * @param buffer The buffer to read data from
51 | * @return The new PDU created from the data
52 | * @throws UnrecoverablePduEncodingException Thrown if there is an unrecoverable
53 | * error while decoding the buffer. Recommended action is to rebind
54 | * the session.
55 | * @throws RecoverablePduEncodingException Thrown if there is recoverable
56 | * error while decoding the buffer. A good example is an optional parameter
57 | * that is invalid or a terminating null byte wasn't found.
58 | */
59 | public Pdu decode(ChannelBuffer buffer) throws UnrecoverablePduException, RecoverablePduException;
60 |
61 | }
--------------------------------------------------------------------------------
/src/main/java/com/cloudhopper/smpp/transcoder/PduTranscoderContext.java:
--------------------------------------------------------------------------------
1 | package com.cloudhopper.smpp.transcoder;
2 |
3 | /*
4 | * #%L
5 | * ch-smpp
6 | * %%
7 | * Copyright (C) 2009 - 2015 Cloudhopper by Twitter
8 | * %%
9 | * Licensed under the Apache License, Version 2.0 (the "License");
10 | * you may not use this file except in compliance with the License.
11 | * You may obtain a copy of the License at
12 | *
13 | * http://www.apache.org/licenses/LICENSE-2.0
14 | *
15 | * Unless required by applicable law or agreed to in writing, software
16 | * distributed under the License is distributed on an "AS IS" BASIS,
17 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18 | * See the License for the specific language governing permissions and
19 | * limitations under the License.
20 | * #L%
21 | */
22 |
23 | /**
24 | * Interface for providing a "context" to the transcoding process for SMPP PDUs.
25 | * For example, custom status messages, sequence number validators, or custom
26 | * TLV tag names, and other logic in the future.
27 | *
28 | * @author joelauer (twitter: @jjlauer or http://twitter.com/jjlauer)
29 | */
30 | public interface PduTranscoderContext {
31 |
32 | /**
33 | * Lookup a "command_status" value and returns a String that represents a result
34 | * message (description) of what the value means. A way to add helpful
35 | * debugging information into logfiles or management interfaces. This value
36 | * is printed out via the toString() method for a PDU response.
37 | *
38 | * @param commandStatus The command_status field to lookup
39 | * @return A String representing a short description of what the command_status
40 | * value represents. For example, a command_status of 0 usually means "OK"
41 | */
42 | public String lookupResultMessage(int commandStatus);
43 |
44 | /**
45 | * Lookup a name for the tag of a TLV and returns a String that represents a
46 | * name for it. A way to add helpful debugging information into logfiles or
47 | * management interfaces.
48 | *
49 | * @param tag The TLV's tag value to lookup
50 | * @return A String representing a short name of what the tag
51 | * value represents. For example, a tag of 0x001E usually means "receipted_message_id"
52 | */
53 | public String lookupTlvTagName(short tag);
54 |
55 | }
56 |
--------------------------------------------------------------------------------
/src/main/java/com/cloudhopper/smpp/type/Address.java:
--------------------------------------------------------------------------------
1 | package com.cloudhopper.smpp.type;
2 |
3 | /*
4 | * #%L
5 | * ch-smpp
6 | * %%
7 | * Copyright (C) 2009 - 2015 Cloudhopper by Twitter
8 | * %%
9 | * Licensed under the Apache License, Version 2.0 (the "License");
10 | * you may not use this file except in compliance with the License.
11 | * You may obtain a copy of the License at
12 | *
13 | * http://www.apache.org/licenses/LICENSE-2.0
14 | *
15 | * Unless required by applicable law or agreed to in writing, software
16 | * distributed under the License is distributed on an "AS IS" BASIS,
17 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18 | * See the License for the specific language governing permissions and
19 | * limitations under the License.
20 | * #L%
21 | */
22 |
23 | import com.cloudhopper.commons.util.HexUtil;
24 | import com.cloudhopper.commons.util.StringUtil;
25 | import com.cloudhopper.smpp.util.ChannelBufferUtil;
26 | import com.cloudhopper.smpp.util.PduUtil;
27 | import org.jboss.netty.buffer.ChannelBuffer;
28 |
29 | /**
30 | * Simple representation of an Address in SMPP.
31 | *
32 | * @author joelauer (twitter: @jjlauer or http://twitter.com/jjlauer)
33 | */
34 | public class Address {
35 |
36 | private byte ton;
37 | private byte npi;
38 | private String address;
39 |
40 | public Address() {
41 | this((byte)0, (byte)0, (String)null);
42 | }
43 |
44 | public Address(byte ton, byte npi, String address) {
45 | this.ton = ton;
46 | this.npi = npi;
47 | this.address = address;
48 | }
49 |
50 | public byte getTon() {
51 | return this.ton;
52 | }
53 |
54 | public void setTon(byte value) {
55 | this.ton = value;
56 | }
57 |
58 | public byte getNpi() {
59 | return this.npi;
60 | }
61 |
62 | public void setNpi(byte value) {
63 | this.npi = value;
64 | }
65 |
66 | public String getAddress() {
67 | return this.address;
68 | }
69 |
70 | public void setAddress(String value) {
71 | this.address = value;
72 | }
73 |
74 | public int calculateByteSize() {
75 | return 2 + PduUtil.calculateByteSizeOfNullTerminatedString(this.address);
76 | }
77 |
78 | public void read(ChannelBuffer buffer) throws UnrecoverablePduException, RecoverablePduException {
79 | this.ton = buffer.readByte();
80 | this.npi = buffer.readByte();
81 | this.address = ChannelBufferUtil.readNullTerminatedString(buffer);
82 | }
83 |
84 | public void write(ChannelBuffer buffer) throws UnrecoverablePduException, RecoverablePduException {
85 | buffer.writeByte(this.ton);
86 | buffer.writeByte(this.npi);
87 | ChannelBufferUtil.writeNullTerminatedString(buffer, this.address);
88 | }
89 |
90 | @Override
91 | public String toString() {
92 | StringBuilder buffer = new StringBuilder(40);
93 | buffer.append("0x");
94 | buffer.append(HexUtil.toHexString(this.ton));
95 | buffer.append(" 0x");
96 | buffer.append(HexUtil.toHexString(this.npi));
97 | buffer.append(" [");
98 | buffer.append(StringUtil.toStringWithNullAsEmpty(this.address));
99 | buffer.append("]");
100 | return buffer.toString();
101 | }
102 | }
103 |
--------------------------------------------------------------------------------
/src/main/java/com/cloudhopper/smpp/type/GenericNackException.java:
--------------------------------------------------------------------------------
1 | package com.cloudhopper.smpp.type;
2 |
3 | /*
4 | * #%L
5 | * ch-smpp
6 | * %%
7 | * Copyright (C) 2009 - 2015 Cloudhopper by Twitter
8 | * %%
9 | * Licensed under the Apache License, Version 2.0 (the "License");
10 | * you may not use this file except in compliance with the License.
11 | * You may obtain a copy of the License at
12 | *
13 | * http://www.apache.org/licenses/LICENSE-2.0
14 | *
15 | * Unless required by applicable law or agreed to in writing, software
16 | * distributed under the License is distributed on an "AS IS" BASIS,
17 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18 | * See the License for the specific language governing permissions and
19 | * limitations under the License.
20 | * #L%
21 | */
22 |
23 | import com.cloudhopper.commons.util.HexUtil;
24 | import com.cloudhopper.smpp.pdu.GenericNack;
25 |
26 | /**
27 | *
28 | * @author joelauer (twitter: @jjlauer or http://twitter.com/jjlauer)
29 | */
30 | public class GenericNackException extends RecoverablePduException {
31 | static final long serialVersionUID = 1L;
32 |
33 | public GenericNackException(GenericNack nack) {
34 | super(buildErrorMessage(nack));
35 | }
36 |
37 | static public String buildErrorMessage(GenericNack nack) {
38 | return "Negative acknowledgement for request [error: 0x" + HexUtil.toHexString(nack.getCommandStatus()) + " \"" + nack.getResultMessage() + "\"]";
39 | }
40 | }
--------------------------------------------------------------------------------
/src/main/java/com/cloudhopper/smpp/type/LoggingOptions.java:
--------------------------------------------------------------------------------
1 | package com.cloudhopper.smpp.type;
2 |
3 | /*
4 | * #%L
5 | * ch-smpp
6 | * %%
7 | * Copyright (C) 2009 - 2015 Cloudhopper by Twitter
8 | * %%
9 | * Licensed under the Apache License, Version 2.0 (the "License");
10 | * you may not use this file except in compliance with the License.
11 | * You may obtain a copy of the License at
12 | *
13 | * http://www.apache.org/licenses/LICENSE-2.0
14 | *
15 | * Unless required by applicable law or agreed to in writing, software
16 | * distributed under the License is distributed on an "AS IS" BASIS,
17 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18 | * See the License for the specific language governing permissions and
19 | * limitations under the License.
20 | * #L%
21 | */
22 |
23 | /**
24 | *
25 | * @author joelauer (twitter: @jjlauer or http://twitter.com/jjlauer)
26 | */
27 | public class LoggingOptions {
28 |
29 | public static final int LOG_PDU = 0x00000001;
30 | public static final int LOG_BYTES = 0x00000002;
31 | public static final int DEFAULT_LOG_OPTION = LOG_PDU;
32 |
33 | private int option;
34 |
35 | public LoggingOptions() {
36 | this.option = DEFAULT_LOG_OPTION;
37 | }
38 |
39 | public void setLogPdu(boolean value) {
40 | if (value) {
41 | this.option |= LOG_PDU;
42 | } else {
43 | this.option &= ~LOG_PDU;
44 | }
45 | }
46 |
47 | public boolean isLogPduEnabled() {
48 | return ((this.option & LOG_PDU) > 0);
49 | }
50 |
51 | public void setLogBytes(boolean value) {
52 | if (value) {
53 | this.option |= LOG_BYTES;
54 | } else {
55 | this.option &= ~LOG_BYTES;
56 | }
57 | }
58 |
59 | public boolean isLogBytesEnabled() {
60 | return ((this.option & LOG_BYTES) > 0);
61 | }
62 | }
63 |
--------------------------------------------------------------------------------
/src/main/java/com/cloudhopper/smpp/type/NotEnoughDataInBufferException.java:
--------------------------------------------------------------------------------
1 | package com.cloudhopper.smpp.type;
2 |
3 | /*
4 | * #%L
5 | * ch-smpp
6 | * %%
7 | * Copyright (C) 2009 - 2015 Cloudhopper by Twitter
8 | * %%
9 | * Licensed under the Apache License, Version 2.0 (the "License");
10 | * you may not use this file except in compliance with the License.
11 | * You may obtain a copy of the License at
12 | *
13 | * http://www.apache.org/licenses/LICENSE-2.0
14 | *
15 | * Unless required by applicable law or agreed to in writing, software
16 | * distributed under the License is distributed on an "AS IS" BASIS,
17 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18 | * See the License for the specific language governing permissions and
19 | * limitations under the License.
20 | * #L%
21 | */
22 |
23 | /**
24 | * Exception that represents more data is required in order to parse an SMPP PDU.
25 | * In as many cases as possible, this exception should include an
26 | * estimate of how many bytes are needed/missing in order to succeed in parsing.
27 | * An estimate of -1 represents an uknown amount of data.
28 | *
29 | * @author joelauer (twitter: @jjlauer or http://twitter.com/jjlauer)
30 | */
31 | public class NotEnoughDataInBufferException extends RecoverablePduException {
32 | static final long serialVersionUID = 1L;
33 |
34 | private int available;
35 | private int expected;
36 |
37 | /**
38 | * Constructs an instance of AtNotEnoughDataInBufferException
39 | * with the specified detail message and estimated number of bytes required.
40 | * An estimate of -1 represents an unknown amount.
41 | * @param msg the detail message.
42 | * @param available Number of bytes that were available
43 | * @param expected Number of bytes expected or -1 if unknown
44 | */
45 | public NotEnoughDataInBufferException(int available, int expected) {
46 | this(null, available, expected);
47 | }
48 |
49 | /**
50 | * Constructs an instance of AtNotEnoughDataInBufferException
51 | * with the specified detail message and estimated number of bytes required.
52 | * An estimate of -1 represents an unknown amount.
53 | * @param msg the detail message.
54 | * @param available Number of bytes that were available
55 | * @param expected Number of bytes expected or -1 if unknown
56 | */
57 | public NotEnoughDataInBufferException(String msg, int available, int expected) {
58 | super("Not enough data in byte buffer to complete encoding/decoding [expected: " + expected + ", available: " + available + "]" + (msg == null ? "" : ": " + msg));
59 | this.available = available;
60 | this.expected = expected;
61 | }
62 |
63 | public int getAvailable() {
64 | return available;
65 | }
66 |
67 | public int getExpected() {
68 | return expected;
69 | }
70 | }
--------------------------------------------------------------------------------
/src/main/java/com/cloudhopper/smpp/type/RecoverablePduException.java:
--------------------------------------------------------------------------------
1 | package com.cloudhopper.smpp.type;
2 |
3 | /*
4 | * #%L
5 | * ch-smpp
6 | * %%
7 | * Copyright (C) 2009 - 2015 Cloudhopper by Twitter
8 | * %%
9 | * Licensed under the Apache License, Version 2.0 (the "License");
10 | * you may not use this file except in compliance with the License.
11 | * You may obtain a copy of the License at
12 | *
13 | * http://www.apache.org/licenses/LICENSE-2.0
14 | *
15 | * Unless required by applicable law or agreed to in writing, software
16 | * distributed under the License is distributed on an "AS IS" BASIS,
17 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18 | * See the License for the specific language governing permissions and
19 | * limitations under the License.
20 | * #L%
21 | */
22 |
23 | import com.cloudhopper.smpp.pdu.Pdu;
24 |
25 | /**
26 | * Thrown when a recoverable PDU decoding error occurs. A recoverable PDU
27 | * error includes the partially decoded PDU in order to generate a negative
28 | * acknowledgement response (if needed).
29 | *
30 | * A good example is that the PDU header was read, but the body of the PDU
31 | * failed to parse correctly.
32 | *
33 | * The recommended action for "recoverable" errors is to return a NACK.
34 | *
35 | * @author joelauer (twitter: @jjlauer or http://twitter.com/jjlauer)
36 | */
37 | public class RecoverablePduException extends Exception {
38 | static final long serialVersionUID = 1L;
39 |
40 | private Pdu partialPdu;
41 |
42 | public RecoverablePduException(String msg) {
43 | super(msg);
44 | }
45 |
46 | public RecoverablePduException(String msg, Throwable t) {
47 | super(msg, t);
48 | }
49 |
50 | public RecoverablePduException(Pdu partialPdu, String msg) {
51 | super(msg);
52 | this.partialPdu = partialPdu;
53 | }
54 |
55 | public RecoverablePduException(Pdu partialPdu, String msg, Throwable t) {
56 | super(msg, t);
57 | this.partialPdu = partialPdu;
58 | }
59 |
60 | public void setPartialPdu(Pdu pdu) {
61 | this.partialPdu = pdu;
62 | }
63 |
64 | public Pdu getPartialPdu() {
65 | return this.partialPdu;
66 | }
67 | }
--------------------------------------------------------------------------------
/src/main/java/com/cloudhopper/smpp/type/SmppBindException.java:
--------------------------------------------------------------------------------
1 | package com.cloudhopper.smpp.type;
2 |
3 | /*
4 | * #%L
5 | * ch-smpp
6 | * %%
7 | * Copyright (C) 2009 - 2015 Cloudhopper by Twitter
8 | * %%
9 | * Licensed under the Apache License, Version 2.0 (the "License");
10 | * you may not use this file except in compliance with the License.
11 | * You may obtain a copy of the License at
12 | *
13 | * http://www.apache.org/licenses/LICENSE-2.0
14 | *
15 | * Unless required by applicable law or agreed to in writing, software
16 | * distributed under the License is distributed on an "AS IS" BASIS,
17 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18 | * See the License for the specific language governing permissions and
19 | * limitations under the License.
20 | * #L%
21 | */
22 |
23 | import com.cloudhopper.commons.util.HexUtil;
24 | import com.cloudhopper.smpp.pdu.BaseBindResp;
25 |
26 | /**
27 | * Thrown only when a "bind" attempt fails and a BaseBindResp was returned.
28 | * This exception can only be created from the BaseBindResp instance which is
29 | * used to create the error message as well.
30 | *
31 | * If no BindResp was received and we timed out while waiting, then an
32 | * SmppTimeoutException or SmppConnectionException would have occurred, not this
33 | * specific error. The underlying status code and mapped message can be figured
34 | * out as well.
35 | *
36 | * @author joelauer (twitter: @jjlauer or http://twitter.com/jjlauer)
37 | */
38 | public class SmppBindException extends UnrecoverablePduException {
39 | static final long serialVersionUID = 1L;
40 |
41 | private final BaseBindResp bindResponse;
42 |
43 | public SmppBindException(BaseBindResp bindResponse) {
44 | super(buildErrorMessage(bindResponse));
45 | this.bindResponse = bindResponse;
46 | }
47 |
48 | public BaseBindResp getBindResponse() {
49 | return this.bindResponse;
50 | }
51 |
52 | static public String buildErrorMessage(BaseBindResp bindResponse) {
53 | if (bindResponse == null) {
54 | return "Bind request failed (response was null)";
55 | } else {
56 | return "Unable to bind [error: 0x" + HexUtil.toHexString(bindResponse.getCommandStatus()) + " \"" + bindResponse.getResultMessage() + "\"]";
57 | }
58 | }
59 |
60 | }
61 |
--------------------------------------------------------------------------------
/src/main/java/com/cloudhopper/smpp/type/SmppChannelConnectException.java:
--------------------------------------------------------------------------------
1 | package com.cloudhopper.smpp.type;
2 |
3 | /*
4 | * #%L
5 | * ch-smpp
6 | * %%
7 | * Copyright (C) 2009 - 2015 Cloudhopper by Twitter
8 | * %%
9 | * Licensed under the Apache License, Version 2.0 (the "License");
10 | * you may not use this file except in compliance with the License.
11 | * You may obtain a copy of the License at
12 | *
13 | * http://www.apache.org/licenses/LICENSE-2.0
14 | *
15 | * Unless required by applicable law or agreed to in writing, software
16 | * distributed under the License is distributed on an "AS IS" BASIS,
17 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18 | * See the License for the specific language governing permissions and
19 | * limitations under the License.
20 | * #L%
21 | */
22 |
23 | /**
24 | * Thrown for exceptions occuring while attempting to connect to a remote
25 | * system and cannot complete within a period of time.
26 | *
27 | * @author joelauer (twitter: @jjlauer or http://twitter.com/jjlauer)
28 | */
29 | public class SmppChannelConnectException extends SmppChannelException {
30 | static final long serialVersionUID = 1L;
31 |
32 | public SmppChannelConnectException(String msg) {
33 | super(msg);
34 | }
35 |
36 | public SmppChannelConnectException(String msg, Throwable t) {
37 | super(msg, t);
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/src/main/java/com/cloudhopper/smpp/type/SmppChannelConnectTimeoutException.java:
--------------------------------------------------------------------------------
1 | package com.cloudhopper.smpp.type;
2 |
3 | /*
4 | * #%L
5 | * ch-smpp
6 | * %%
7 | * Copyright (C) 2009 - 2015 Cloudhopper by Twitter
8 | * %%
9 | * Licensed under the Apache License, Version 2.0 (the "License");
10 | * you may not use this file except in compliance with the License.
11 | * You may obtain a copy of the License at
12 | *
13 | * http://www.apache.org/licenses/LICENSE-2.0
14 | *
15 | * Unless required by applicable law or agreed to in writing, software
16 | * distributed under the License is distributed on an "AS IS" BASIS,
17 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18 | * See the License for the specific language governing permissions and
19 | * limitations under the License.
20 | * #L%
21 | */
22 |
23 | /**
24 | * Thrown for exceptions occuring while attempting to connect to a remote
25 | * system and cannot complete within a period of time.
26 | *
27 | * @author joelauer (twitter: @jjlauer or http://twitter.com/jjlauer)
28 | */
29 | public class SmppChannelConnectTimeoutException extends SmppChannelConnectException {
30 | static final long serialVersionUID = 1L;
31 |
32 | public SmppChannelConnectTimeoutException(String msg) {
33 | super(msg);
34 | }
35 |
36 | public SmppChannelConnectTimeoutException(String msg, Throwable t) {
37 | super(msg, t);
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/src/main/java/com/cloudhopper/smpp/type/SmppChannelException.java:
--------------------------------------------------------------------------------
1 | package com.cloudhopper.smpp.type;
2 |
3 | /*
4 | * #%L
5 | * ch-smpp
6 | * %%
7 | * Copyright (C) 2009 - 2015 Cloudhopper by Twitter
8 | * %%
9 | * Licensed under the Apache License, Version 2.0 (the "License");
10 | * you may not use this file except in compliance with the License.
11 | * You may obtain a copy of the License at
12 | *
13 | * http://www.apache.org/licenses/LICENSE-2.0
14 | *
15 | * Unless required by applicable law or agreed to in writing, software
16 | * distributed under the License is distributed on an "AS IS" BASIS,
17 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18 | * See the License for the specific language governing permissions and
19 | * limitations under the License.
20 | * #L%
21 | */
22 |
23 | /**
24 | * Thrown for exceptions occurring with the underlying Channel or TCP/IP
25 | * connection such as read/write errors, closed connections, etc.
26 | *
27 | * Its best to restart a session if this occurs.
28 | *
29 | * @author joelauer (twitter: @jjlauer or http://twitter.com/jjlauer)
30 | */
31 | public class SmppChannelException extends Exception {
32 | static final long serialVersionUID = 1L;
33 |
34 | public SmppChannelException(String msg) {
35 | super(msg);
36 | }
37 |
38 | public SmppChannelException(String msg, Throwable t) {
39 | super(msg, t);
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/src/main/java/com/cloudhopper/smpp/type/SmppConnectionConfiguration.java:
--------------------------------------------------------------------------------
1 | package com.cloudhopper.smpp.type;
2 |
3 | /*
4 | * #%L
5 | * ch-smpp
6 | * %%
7 | * Copyright (C) 2009 - 2015 Cloudhopper by Twitter
8 | * %%
9 | * Licensed under the Apache License, Version 2.0 (the "License");
10 | * you may not use this file except in compliance with the License.
11 | * You may obtain a copy of the License at
12 | *
13 | * http://www.apache.org/licenses/LICENSE-2.0
14 | *
15 | * Unless required by applicable law or agreed to in writing, software
16 | * distributed under the License is distributed on an "AS IS" BASIS,
17 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18 | * See the License for the specific language governing permissions and
19 | * limitations under the License.
20 | * #L%
21 | */
22 |
23 | import com.cloudhopper.smpp.SmppConstants;
24 |
25 | /**
26 | * Configuration to create a TCP/IP connection (Channel) for an SmppSession.
27 | *
28 | * @author joelauer (twitter: @jjlauer or http://twitter.com/jjlauer)
29 | */
30 | public class SmppConnectionConfiguration {
31 |
32 | private String host;
33 | private int port;
34 | private long connectTimeout;
35 |
36 | public SmppConnectionConfiguration() {
37 | this(null, 0, SmppConstants.DEFAULT_CONNECT_TIMEOUT);
38 | }
39 |
40 | public SmppConnectionConfiguration(String host, int port, long connectTimeout) {
41 | this.host = host;
42 | this.port = port;
43 | this.connectTimeout = connectTimeout;
44 | }
45 |
46 | public void setHost(String value) {
47 | this.host = value;
48 | }
49 |
50 | public String getHost() {
51 | return this.host;
52 | }
53 |
54 | public void setPort(int value) {
55 | this.port = value;
56 | }
57 |
58 | public int getPort() {
59 | return this.port;
60 | }
61 |
62 | public void setConnectTimeout(long value) {
63 | this.connectTimeout = value;
64 | }
65 |
66 | public long getConnectTimeout() {
67 | return this.connectTimeout;
68 | }
69 |
70 | }
71 |
--------------------------------------------------------------------------------
/src/main/java/com/cloudhopper/smpp/type/SmppInvalidArgumentException.java:
--------------------------------------------------------------------------------
1 | package com.cloudhopper.smpp.type;
2 |
3 | /*
4 | * #%L
5 | * ch-smpp
6 | * %%
7 | * Copyright (C) 2009 - 2015 Cloudhopper by Twitter
8 | * %%
9 | * Licensed under the Apache License, Version 2.0 (the "License");
10 | * you may not use this file except in compliance with the License.
11 | * You may obtain a copy of the License at
12 | *
13 | * http://www.apache.org/licenses/LICENSE-2.0
14 | *
15 | * Unless required by applicable law or agreed to in writing, software
16 | * distributed under the License is distributed on an "AS IS" BASIS,
17 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18 | * See the License for the specific language governing permissions and
19 | * limitations under the License.
20 | * #L%
21 | */
22 |
23 | /**
24 | * Thrown when an argument was used that is invalid.
25 | *
26 | * @author joelauer (twitter: @jjlauer or http://twitter.com/jjlauer)
27 | */
28 | public class SmppInvalidArgumentException extends RecoverablePduException {
29 | static final long serialVersionUID = 1L;
30 |
31 | public SmppInvalidArgumentException(String msg) {
32 | super(null, msg);
33 | }
34 |
35 | public SmppInvalidArgumentException(String msg, Throwable t) {
36 | super(null, msg, t);
37 | }
38 | }
--------------------------------------------------------------------------------
/src/main/java/com/cloudhopper/smpp/type/SmppProcessingException.java:
--------------------------------------------------------------------------------
1 | package com.cloudhopper.smpp.type;
2 |
3 | /*
4 | * #%L
5 | * ch-smpp
6 | * %%
7 | * Copyright (C) 2009 - 2015 Cloudhopper by Twitter
8 | * %%
9 | * Licensed under the Apache License, Version 2.0 (the "License");
10 | * you may not use this file except in compliance with the License.
11 | * You may obtain a copy of the License at
12 | *
13 | * http://www.apache.org/licenses/LICENSE-2.0
14 | *
15 | * Unless required by applicable law or agreed to in writing, software
16 | * distributed under the License is distributed on an "AS IS" BASIS,
17 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18 | * See the License for the specific language governing permissions and
19 | * limitations under the License.
20 | * #L%
21 | */
22 |
23 | import com.cloudhopper.commons.util.HexUtil;
24 |
25 | /**
26 | * Thrown for exceptions while processing an SMPP request.
27 | *
28 | * @author joelauer (twitter: @jjlauer or http://twitter.com/jjlauer)
29 | */
30 | public class SmppProcessingException extends Exception {
31 | static final long serialVersionUID = 1L;
32 |
33 | private int errorCode;
34 |
35 | public SmppProcessingException(int errorCode) {
36 | this(errorCode, null);
37 | }
38 |
39 | public SmppProcessingException(int errorCode, String msg) {
40 | super("SMPP processing error [0x" + HexUtil.toHexString(errorCode) + "]" + (msg == null ? "" : " message [" + msg + "]"));
41 | this.errorCode = errorCode;
42 | }
43 |
44 | public int getErrorCode() {
45 | return this.errorCode;
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/src/main/java/com/cloudhopper/smpp/type/SmppTimeoutException.java:
--------------------------------------------------------------------------------
1 | package com.cloudhopper.smpp.type;
2 |
3 | /*
4 | * #%L
5 | * ch-smpp
6 | * %%
7 | * Copyright (C) 2009 - 2015 Cloudhopper by Twitter
8 | * %%
9 | * Licensed under the Apache License, Version 2.0 (the "License");
10 | * you may not use this file except in compliance with the License.
11 | * You may obtain a copy of the License at
12 | *
13 | * http://www.apache.org/licenses/LICENSE-2.0
14 | *
15 | * Unless required by applicable law or agreed to in writing, software
16 | * distributed under the License is distributed on an "AS IS" BASIS,
17 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18 | * See the License for the specific language governing permissions and
19 | * limitations under the License.
20 | * #L%
21 | */
22 |
23 | /**
24 | * Thrown specifically when an operation times out vs. some sort of underlying
25 | * I/O exception like the channel was closed.
26 | *
27 | * @author joelauer (twitter: @jjlauer or http://twitter.com/jjlauer)
28 | */
29 | public class SmppTimeoutException extends Exception {
30 | static final long serialVersionUID = 1L;
31 |
32 | public SmppTimeoutException(String msg) {
33 | super(msg);
34 | }
35 |
36 | public SmppTimeoutException(String msg, Throwable t) {
37 | super(msg, t);
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/src/main/java/com/cloudhopper/smpp/type/TerminatingNullByteNotFoundException.java:
--------------------------------------------------------------------------------
1 | package com.cloudhopper.smpp.type;
2 |
3 | /*
4 | * #%L
5 | * ch-smpp
6 | * %%
7 | * Copyright (C) 2009 - 2015 Cloudhopper by Twitter
8 | * %%
9 | * Licensed under the Apache License, Version 2.0 (the "License");
10 | * you may not use this file except in compliance with the License.
11 | * You may obtain a copy of the License at
12 | *
13 | * http://www.apache.org/licenses/LICENSE-2.0
14 | *
15 | * Unless required by applicable law or agreed to in writing, software
16 | * distributed under the License is distributed on an "AS IS" BASIS,
17 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18 | * See the License for the specific language governing permissions and
19 | * limitations under the License.
20 | * #L%
21 | */
22 |
23 | /**
24 | *
25 | * @author joelauer (twitter: @jjlauer or http://twitter.com/jjlauer)
26 | */
27 | public class TerminatingNullByteNotFoundException extends RecoverablePduException {
28 | static final long serialVersionUID = 1L;
29 |
30 | public TerminatingNullByteNotFoundException(String msg) {
31 | super(msg);
32 | }
33 |
34 | public TerminatingNullByteNotFoundException(String msg, Throwable t) {
35 | super(msg, t);
36 | }
37 | }
--------------------------------------------------------------------------------
/src/main/java/com/cloudhopper/smpp/type/UnexpectedPduResponseException.java:
--------------------------------------------------------------------------------
1 | package com.cloudhopper.smpp.type;
2 |
3 | /*
4 | * #%L
5 | * ch-smpp
6 | * %%
7 | * Copyright (C) 2009 - 2015 Cloudhopper by Twitter
8 | * %%
9 | * Licensed under the Apache License, Version 2.0 (the "License");
10 | * you may not use this file except in compliance with the License.
11 | * You may obtain a copy of the License at
12 | *
13 | * http://www.apache.org/licenses/LICENSE-2.0
14 | *
15 | * Unless required by applicable law or agreed to in writing, software
16 | * distributed under the License is distributed on an "AS IS" BASIS,
17 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18 | * See the License for the specific language governing permissions and
19 | * limitations under the License.
20 | * #L%
21 | */
22 |
23 | import com.cloudhopper.commons.util.HexUtil;
24 | import com.cloudhopper.smpp.pdu.PduResponse;
25 |
26 | /**
27 | *
28 | * @author joelauer (twitter: @jjlauer or http://twitter.com/jjlauer)
29 | */
30 | public class UnexpectedPduResponseException extends UnrecoverablePduException {
31 | static final long serialVersionUID = 1L;
32 |
33 | private final PduResponse responsePdu;
34 |
35 | public UnexpectedPduResponseException(PduResponse responsePdu) {
36 | super(buildErrorMessage(responsePdu));
37 | this.responsePdu = responsePdu;
38 | }
39 |
40 | public PduResponse getResponsePdu() {
41 | return this.responsePdu;
42 | }
43 |
44 | static public String buildErrorMessage(PduResponse responsePdu) {
45 | return "Unexpected response PDU [" + responsePdu.getClass().getName() + "] [error: 0x" + HexUtil.toHexString(responsePdu.getCommandStatus()) + " \"" + responsePdu.getResultMessage() + "\"]";
46 | }
47 | }
--------------------------------------------------------------------------------
/src/main/java/com/cloudhopper/smpp/type/UnknownCommandIdException.java:
--------------------------------------------------------------------------------
1 | package com.cloudhopper.smpp.type;
2 |
3 | /*
4 | * #%L
5 | * ch-smpp
6 | * %%
7 | * Copyright (C) 2009 - 2015 Cloudhopper by Twitter
8 | * %%
9 | * Licensed under the Apache License, Version 2.0 (the "License");
10 | * you may not use this file except in compliance with the License.
11 | * You may obtain a copy of the License at
12 | *
13 | * http://www.apache.org/licenses/LICENSE-2.0
14 | *
15 | * Unless required by applicable law or agreed to in writing, software
16 | * distributed under the License is distributed on an "AS IS" BASIS,
17 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18 | * See the License for the specific language governing permissions and
19 | * limitations under the License.
20 | * #L%
21 | */
22 |
23 | import com.cloudhopper.smpp.pdu.Pdu;
24 |
25 | /**
26 | * Thrown when an unsupported or invalid Command ID was decoded. This is likely
27 | * a recoverable error. The recommended action is to either return a NAK or
28 | * a specific SMPP error code.
29 | *
30 | * @author joelauer (twitter: @jjlauer or http://twitter.com/jjlauer)
31 | */
32 | public class UnknownCommandIdException extends RecoverablePduException {
33 | static final long serialVersionUID = 1L;
34 |
35 | public UnknownCommandIdException(Pdu partialPdu, String msg) {
36 | super(partialPdu, msg);
37 | }
38 |
39 | public UnknownCommandIdException(Pdu partialPdu, String msg, Throwable t) {
40 | super(partialPdu, msg, t);
41 | }
42 | }
--------------------------------------------------------------------------------
/src/main/java/com/cloudhopper/smpp/type/UnrecoverablePduException.java:
--------------------------------------------------------------------------------
1 | package com.cloudhopper.smpp.type;
2 |
3 | /*
4 | * #%L
5 | * ch-smpp
6 | * %%
7 | * Copyright (C) 2009 - 2015 Cloudhopper by Twitter
8 | * %%
9 | * Licensed under the Apache License, Version 2.0 (the "License");
10 | * you may not use this file except in compliance with the License.
11 | * You may obtain a copy of the License at
12 | *
13 | * http://www.apache.org/licenses/LICENSE-2.0
14 | *
15 | * Unless required by applicable law or agreed to in writing, software
16 | * distributed under the License is distributed on an "AS IS" BASIS,
17 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18 | * See the License for the specific language governing permissions and
19 | * limitations under the License.
20 | * #L%
21 | */
22 |
23 | /**
24 | * Thrown when an unrecoverable PDU decoding error occurs. A good example is
25 | * a PDU length that is so large its signed negative (31st bit is 1). This is
26 | * an impossible error and likely means something is drastically wrong with
27 | * the sequence of bytes.
28 | *
29 | * Another example is an invalid sequence number in an invalid range. If
30 | * an invalid sequenceNumber is used, the recommended action is to close the
31 | * session.
32 | *
33 | * The recommended action for an unrecoverable error is to close the SMPP
34 | * connection.
35 | *
36 | * @author joelauer (twitter: @jjlauer or http://twitter.com/jjlauer)
37 | */
38 | public class UnrecoverablePduException extends Exception {
39 | static final long serialVersionUID = 1L;
40 |
41 | public UnrecoverablePduException(String msg) {
42 | super(msg);
43 | }
44 |
45 | public UnrecoverablePduException(String msg, Throwable t) {
46 | super(msg, t);
47 | }
48 | }
--------------------------------------------------------------------------------
/src/main/java/com/cloudhopper/smpp/type/UnsucessfulSME.java:
--------------------------------------------------------------------------------
1 | /**
2 | *
3 | */
4 | package com.cloudhopper.smpp.type;
5 |
6 | /*
7 | * #%L
8 | * ch-smpp
9 | * %%
10 | * Copyright (C) 2009 - 2013 Cloudhopper by Twitter
11 | * %%
12 | * Licensed under the Apache License, Version 2.0 (the "License");
13 | * you may not use this file except in compliance with the License.
14 | * You may obtain a copy of the License at
15 | *
16 | * http://www.apache.org/licenses/LICENSE-2.0
17 | *
18 | * Unless required by applicable law or agreed to in writing, software
19 | * distributed under the License is distributed on an "AS IS" BASIS,
20 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
21 | * See the License for the specific language governing permissions and
22 | * limitations under the License.
23 | * #L%
24 | */
25 |
26 | import org.jboss.netty.buffer.ChannelBuffer;
27 |
28 | import com.cloudhopper.smpp.util.ChannelBufferUtil;
29 |
30 | /**
31 | * @author Amit Bhayani
32 | *
33 | */
34 | public class UnsucessfulSME {
35 |
36 | private int errorStatusCode;
37 | private Address address;
38 |
39 | /**
40 | *
41 | */
42 | public UnsucessfulSME() {
43 | }
44 |
45 | public UnsucessfulSME(int errorStatusCode, Address address) {
46 | super();
47 | this.errorStatusCode = errorStatusCode;
48 | this.address = address;
49 | }
50 |
51 | public int getErrorStatusCode() {
52 | return errorStatusCode;
53 | }
54 |
55 | public void setErrorStatusCode(int errorStatusCode) {
56 | this.errorStatusCode = errorStatusCode;
57 | }
58 |
59 | public Address getAddress() {
60 | return address;
61 | }
62 |
63 | public void setAddress(Address address) {
64 | this.address = address;
65 | }
66 |
67 | public void read(ChannelBuffer buffer) throws UnrecoverablePduException,
68 | RecoverablePduException {
69 | this.address = ChannelBufferUtil.readAddress(buffer);
70 | this.errorStatusCode = buffer.readInt();
71 | }
72 |
73 | public void write(ChannelBuffer buffer) throws UnrecoverablePduException,
74 | RecoverablePduException {
75 | ChannelBufferUtil.writeAddress(buffer, this.address);
76 | buffer.writeInt(this.errorStatusCode);
77 | }
78 |
79 | @Override
80 | public String toString() {
81 | StringBuilder buffer = new StringBuilder(44);
82 | buffer.append(this.address.toString());
83 | buffer.append(" errorStatusCode [");
84 | buffer.append(this.errorStatusCode);
85 | buffer.append("]");
86 | return buffer.toString();
87 | }
88 |
89 | }
90 |
--------------------------------------------------------------------------------
/src/main/java/com/cloudhopper/smpp/util/DaemonExecutors.java:
--------------------------------------------------------------------------------
1 | package com.cloudhopper.smpp.util;
2 |
3 | /*
4 | * #%L
5 | * ch-smpp
6 | * %%
7 | * Copyright (C) 2009 - 2015 Cloudhopper by Twitter
8 | * %%
9 | * Licensed under the Apache License, Version 2.0 (the "License");
10 | * you may not use this file except in compliance with the License.
11 | * You may obtain a copy of the License at
12 | *
13 | * http://www.apache.org/licenses/LICENSE-2.0
14 | *
15 | * Unless required by applicable law or agreed to in writing, software
16 | * distributed under the License is distributed on an "AS IS" BASIS,
17 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18 | * See the License for the specific language governing permissions and
19 | * limitations under the License.
20 | * #L%
21 | */
22 |
23 | import java.util.concurrent.ExecutorService;
24 | import java.util.concurrent.Executors;
25 | import java.util.concurrent.ThreadFactory;
26 |
27 | /**
28 | *
29 | * @author joelauer (twitter: @jjlauer or http://twitter.com/jjlauer)
30 | */
31 | public class DaemonExecutors {
32 |
33 | /**
34 | * Utility method for creating a cached pool of "daemon" threads. A daemon
35 | * thread does not limit the JVM from exiting if they aren't shutdown.
36 | * @return A new cached pool of daemon threads
37 | */
38 | static public ExecutorService newCachedDaemonThreadPool() {
39 | return Executors.newCachedThreadPool(new ThreadFactory() {
40 | @Override
41 | public Thread newThread(Runnable r) {
42 | Thread t = new Thread(r);
43 | t.setDaemon(true);
44 | return t;
45 | }
46 | });
47 | }
48 |
49 | }
50 |
--------------------------------------------------------------------------------
/src/main/java/com/cloudhopper/smpp/util/DeliveryReceiptException.java:
--------------------------------------------------------------------------------
1 | package com.cloudhopper.smpp.util;
2 |
3 | /*
4 | * #%L
5 | * ch-smpp
6 | * %%
7 | * Copyright (C) 2009 - 2015 Cloudhopper by Twitter
8 | * %%
9 | * Licensed under the Apache License, Version 2.0 (the "License");
10 | * you may not use this file except in compliance with the License.
11 | * You may obtain a copy of the License at
12 | *
13 | * http://www.apache.org/licenses/LICENSE-2.0
14 | *
15 | * Unless required by applicable law or agreed to in writing, software
16 | * distributed under the License is distributed on an "AS IS" BASIS,
17 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18 | * See the License for the specific language governing permissions and
19 | * limitations under the License.
20 | * #L%
21 | */
22 |
23 | /**
24 | *
25 | * @author joelauer (twitter: @jjlauer or http://twitter.com/jjlauer)
26 | */
27 | public class DeliveryReceiptException extends Exception {
28 |
29 | /**
30 | * Constructs an instance of DeliveryReceiptException
with the specified detail message.
31 | * @param msg the detail message.
32 | */
33 | public DeliveryReceiptException(String msg) {
34 | super(msg);
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/src/main/java/com/cloudhopper/smpp/util/InvalidSequenceNumberException.java:
--------------------------------------------------------------------------------
1 | package com.cloudhopper.smpp.util;
2 |
3 | /*
4 | * #%L
5 | * ch-smpp
6 | * %%
7 | * Copyright (C) 2009 - 2015 Cloudhopper by Twitter
8 | * %%
9 | * Licensed under the Apache License, Version 2.0 (the "License");
10 | * you may not use this file except in compliance with the License.
11 | * You may obtain a copy of the License at
12 | *
13 | * http://www.apache.org/licenses/LICENSE-2.0
14 | *
15 | * Unless required by applicable law or agreed to in writing, software
16 | * distributed under the License is distributed on an "AS IS" BASIS,
17 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18 | * See the License for the specific language governing permissions and
19 | * limitations under the License.
20 | * #L%
21 | */
22 |
23 | import com.cloudhopper.smpp.type.UnrecoverablePduException;
24 | import com.cloudhopper.smpp.pdu.*;
25 |
26 | /**
27 | * Thrown if a sequence number is not valid.
28 | *
29 | * @author joelauer (twitter: @jjlauer or http://twitter.com/jjlauer)
30 | */
31 | public class InvalidSequenceNumberException extends UnrecoverablePduException {
32 | static final long serialVersionUID = 1L;
33 |
34 | public InvalidSequenceNumberException(String msg) {
35 | super(msg);
36 | }
37 |
38 | public InvalidSequenceNumberException(String msg, Throwable t) {
39 | super(msg, t);
40 | }
41 | }
--------------------------------------------------------------------------------
/src/main/java/com/cloudhopper/smpp/util/PduUtil.java:
--------------------------------------------------------------------------------
1 | package com.cloudhopper.smpp.util;
2 |
3 | /*
4 | * #%L
5 | * ch-smpp
6 | * %%
7 | * Copyright (C) 2009 - 2015 Cloudhopper by Twitter
8 | * %%
9 | * Licensed under the Apache License, Version 2.0 (the "License");
10 | * you may not use this file except in compliance with the License.
11 | * You may obtain a copy of the License at
12 | *
13 | * http://www.apache.org/licenses/LICENSE-2.0
14 | *
15 | * Unless required by applicable law or agreed to in writing, software
16 | * distributed under the License is distributed on an "AS IS" BASIS,
17 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18 | * See the License for the specific language governing permissions and
19 | * limitations under the License.
20 | * #L%
21 | */
22 |
23 | import com.cloudhopper.smpp.SmppConstants;
24 | import com.cloudhopper.smpp.type.Address;
25 |
26 | /**
27 | *
28 | * @author joelauer (twitter: @jjlauer or http://twitter.com/jjlauer)
29 | */
30 | public class PduUtil {
31 |
32 | /**
33 | * Calculates size of a "C-String" by returning the length of the String
34 | * plus 1 (for the NULL byte). If the parameter is null, will return 1.
35 | * @param value
36 | * @return
37 | */
38 | static public int calculateByteSizeOfNullTerminatedString(String value) {
39 | if (value == null) {
40 | return 1;
41 | }
42 | return value.length() + 1;
43 | }
44 |
45 | /**
46 | * Calculates the byte size of an Address. Safe to call with nulls as a
47 | * parameter since this will then just return the size of an empty address.
48 | * @param value
49 | * @return
50 | */
51 | static public int calculateByteSizeOfAddress(Address value) {
52 | if (value == null) {
53 | return SmppConstants.EMPTY_ADDRESS.calculateByteSize();
54 | } else {
55 | return value.calculateByteSize();
56 | }
57 | }
58 |
59 | static public boolean isRequestCommandId(int commandId) {
60 | // if the 31st bit is not set, this is a request
61 | return ((commandId & SmppConstants.PDU_CMD_ID_RESP_MASK) == 0);
62 | }
63 |
64 | static public boolean isResponseCommandId(int commandId) {
65 | // if the 31st bit is not set, this is a request
66 | return ((commandId & SmppConstants.PDU_CMD_ID_RESP_MASK) == SmppConstants.PDU_CMD_ID_RESP_MASK);
67 | }
68 | }
69 |
--------------------------------------------------------------------------------
/src/main/java/com/cloudhopper/smpp/util/SequenceNumber.java:
--------------------------------------------------------------------------------
1 | package com.cloudhopper.smpp.util;
2 |
3 | /*
4 | * #%L
5 | * ch-smpp
6 | * %%
7 | * Copyright (C) 2009 - 2015 Cloudhopper by Twitter
8 | * %%
9 | * Licensed under the Apache License, Version 2.0 (the "License");
10 | * you may not use this file except in compliance with the License.
11 | * You may obtain a copy of the License at
12 | *
13 | * http://www.apache.org/licenses/LICENSE-2.0
14 | *
15 | * Unless required by applicable law or agreed to in writing, software
16 | * distributed under the License is distributed on an "AS IS" BASIS,
17 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18 | * See the License for the specific language governing permissions and
19 | * limitations under the License.
20 | * #L%
21 | */
22 |
23 | /**
24 | * Utility class for atomically generating SMPP PDU sequence numbers. This
25 | * implementation will atomically increment the sequence number and wrap it
26 | * around back to 1 when it hits the max 0x7FFFFFFF.
27 | *
28 | * @author joelauer (twitter: @jjlauer or http://twitter.com/jjlauer)
29 | */
30 | public class SequenceNumber {
31 |
32 | // AT&T Wireless uses a sequence number of 0 to start. This violates SMPP 3.4
33 | // specifications of the valid range of sequence numbers, but we'll need
34 | // to permit it.
35 | public static final int MIN_VALUE = 0x00000000;
36 | public static final int DEFAULT_VALUE = 0x00000001;
37 | public static final int MAX_VALUE = 0x7FFFFFFF;
38 |
39 | private int value;
40 |
41 | public SequenceNumber() {
42 | this.value = DEFAULT_VALUE;
43 | }
44 |
45 | public SequenceNumber(int initialValue) throws InvalidSequenceNumberException {
46 | assertValid(initialValue);
47 | this.value = initialValue;
48 | }
49 |
50 | /**
51 | * Get the next number in this sequence's scheme. This method is synchronized
52 | * so its safe for multiple threads to call.
53 | */
54 | synchronized public int next() {
55 | // the next value is the current value
56 | int nextValue = this.value;
57 |
58 | if (this.value == MAX_VALUE) {
59 | // wrap this around back to 1
60 | this.value = DEFAULT_VALUE;
61 | } else {
62 | this.value++;
63 | }
64 |
65 | return nextValue;
66 | }
67 |
68 | /**
69 | * Get the next number in this sequence's scheme without causing it to move
70 | * to the next-in-sequence. This method returns the number that will be
71 | * returned by the next call to next()
without actually
72 | * increasing the sequence. Multiple calls to peek
will
73 | * return the same number until a call to next()
is made.
74 | */
75 | synchronized public int peek() {
76 | return this.value;
77 | }
78 |
79 | /**
80 | * Reset the sequence scheme to the beginning of the sequence (min value
81 | * which is 1).
82 | */
83 | synchronized public void reset() {
84 | this.value = DEFAULT_VALUE;
85 | }
86 |
87 | static public void assertValid(int sequenceNumber) throws InvalidSequenceNumberException {
88 | // turns out that some operators ignore the specifications and actually
89 | // use all 32 bits of the sequence number -- instead of validating it
90 | // we'll just assert that everything is valid
91 | /**
92 | if (sequenceNumber < MIN_VALUE || sequenceNumber > MAX_VALUE) {
93 | throw new InvalidSequenceNumberException("Sequence number [" + sequenceNumber + "] is not in range from " + MIN_VALUE + " to " + MAX_VALUE);
94 | }
95 | */
96 | }
97 | }
98 |
99 |
--------------------------------------------------------------------------------
/src/main/java/com/cloudhopper/smpp/util/SmppSessionUtil.java:
--------------------------------------------------------------------------------
1 | package com.cloudhopper.smpp.util;
2 |
3 | /*
4 | * #%L
5 | * ch-smpp
6 | * %%
7 | * Copyright (C) 2009 - 2015 Cloudhopper by Twitter
8 | * %%
9 | * Licensed under the Apache License, Version 2.0 (the "License");
10 | * you may not use this file except in compliance with the License.
11 | * You may obtain a copy of the License at
12 | *
13 | * http://www.apache.org/licenses/LICENSE-2.0
14 | *
15 | * Unless required by applicable law or agreed to in writing, software
16 | * distributed under the License is distributed on an "AS IS" BASIS,
17 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18 | * See the License for the specific language governing permissions and
19 | * limitations under the License.
20 | * #L%
21 | */
22 |
23 | import com.cloudhopper.smpp.SmppSession;
24 | import com.cloudhopper.smpp.pdu.GenericNack;
25 | import com.cloudhopper.smpp.pdu.PduRequest;
26 | import com.cloudhopper.smpp.pdu.PduResponse;
27 | import com.cloudhopper.smpp.type.GenericNackException;
28 | import com.cloudhopper.smpp.type.UnexpectedPduResponseException;
29 | import org.slf4j.Logger;
30 | import org.slf4j.LoggerFactory;
31 |
32 | /**
33 | *
34 | * @author joelauer (twitter: @jjlauer or http://twitter.com/jjlauer)
35 | */
36 | public class SmppSessionUtil {
37 | private static final Logger logger = LoggerFactory.getLogger(SmppSessionUtil.class);
38 |
39 | static public void close(SmppSession session) {
40 | if (session != null) {
41 | try {
42 | session.close();
43 | } catch (Throwable t) {
44 | logger.warn("Unable to cleanly close session: {}", t);
45 | }
46 | }
47 | }
48 |
49 | /**
50 | * Asserts that a PDU response matches a PDU request. A good example is that
51 | * a PDU response may be a "Generic_Nack" to our request.
52 | * @param request The PDU request
53 | * @param response The PDU response
54 | * @throws GenericNackException Thrown if the response was a "Generic_Nack"
55 | * @throws UnexpectedPduResponseException Thrown if the response type did
56 | * not match the request type. For example, if the request was a
57 | * "submit_sm", but the response was "data_sm_resp".
58 | */
59 | static public void assertExpectedResponse(PduRequest request, PduResponse response) throws GenericNackException, UnexpectedPduResponseException {
60 | if (request.getResponseClass().isInstance(response)) {
61 | return;
62 | } else if (response instanceof GenericNack) {
63 | throw new GenericNackException((GenericNack)response);
64 | } else {
65 | throw new UnexpectedPduResponseException(response);
66 | }
67 | }
68 | }
--------------------------------------------------------------------------------
/src/test/java/com/cloudhopper/smpp/demo/DeliveryReceiptMain.java:
--------------------------------------------------------------------------------
1 | package com.cloudhopper.smpp.demo;
2 |
3 | /*
4 | * #%L
5 | * ch-smpp
6 | * %%
7 | * Copyright (C) 2009 - 2015 Cloudhopper by Twitter
8 | * %%
9 | * Licensed under the Apache License, Version 2.0 (the "License");
10 | * you may not use this file except in compliance with the License.
11 | * You may obtain a copy of the License at
12 | *
13 | * http://www.apache.org/licenses/LICENSE-2.0
14 | *
15 | * Unless required by applicable law or agreed to in writing, software
16 | * distributed under the License is distributed on an "AS IS" BASIS,
17 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18 | * See the License for the specific language governing permissions and
19 | * limitations under the License.
20 | * #L%
21 | */
22 |
23 | import com.cloudhopper.smpp.util.DeliveryReceipt;
24 | import org.joda.time.DateTimeZone;
25 | import org.slf4j.Logger;
26 | import org.slf4j.LoggerFactory;
27 |
28 | /**
29 | *
30 | * @author joelauer (twitter: @jjlauer or http://twitter.com/jjlauer)
31 | */
32 | public class DeliveryReceiptMain {
33 | private static final Logger logger = LoggerFactory.getLogger(DeliveryReceiptMain.class);
34 |
35 | static public void main(String[] args) throws Exception {
36 | //DeliveryReceipt dlr = DeliveryReceipt.parseShortMessage("id:4 sub:001 dlvrd:001 submit date:1006020051 done date:1006020051 stat:DELIVRD err:000 Text:Hello", DateTimeZone.UTC, true);
37 |
38 | //DeliveryReceipt dlr = DeliveryReceipt.parseShortMessage("sub:001 id:4 dlvrd:001 done date:1006020051 stat:DELIVRD submit date:1006020051 err:000 Text:Hello", DateTimeZone.UTC, true);
39 |
40 | //DeliveryReceipt dlr = DeliveryReceipt.parseShortMessage("sub:001 id:4 dlvrd:001 done date:1006020051 stat:DELIVRD submit date:1006020051 err:000 text:", DateTimeZone.UTC, true);
41 |
42 | DeliveryReceipt dlr = DeliveryReceipt.parseShortMessage("id:2E179B310EDE971B2760C72B7F026E1B submit date:20110314181534 done date:20110314181741 stat:DELIVRD err:0", DateTimeZone.UTC, false);
43 |
44 | logger.debug("{}", dlr);
45 | }
46 |
47 | }
--------------------------------------------------------------------------------
/src/test/java/com/cloudhopper/smpp/demo/ParserMain.java:
--------------------------------------------------------------------------------
1 | package com.cloudhopper.smpp.demo;
2 |
3 | /*
4 | * #%L
5 | * ch-smpp
6 | * %%
7 | * Copyright (C) 2009 - 2015 Cloudhopper by Twitter
8 | * %%
9 | * Licensed under the Apache License, Version 2.0 (the "License");
10 | * you may not use this file except in compliance with the License.
11 | * You may obtain a copy of the License at
12 | *
13 | * http://www.apache.org/licenses/LICENSE-2.0
14 | *
15 | * Unless required by applicable law or agreed to in writing, software
16 | * distributed under the License is distributed on an "AS IS" BASIS,
17 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18 | * See the License for the specific language governing permissions and
19 | * limitations under the License.
20 | * #L%
21 | */
22 |
23 | import com.cloudhopper.smpp.pdu.BufferHelper;
24 | import com.cloudhopper.smpp.pdu.Pdu;
25 | import com.cloudhopper.smpp.transcoder.DefaultPduTranscoder;
26 | import com.cloudhopper.smpp.transcoder.DefaultPduTranscoderContext;
27 | import com.cloudhopper.smpp.transcoder.PduTranscoder;
28 | import com.cloudhopper.smpp.transcoder.PduTranscoderContext;
29 | import org.jboss.netty.buffer.ChannelBuffer;
30 | import org.slf4j.Logger;
31 | import org.slf4j.LoggerFactory;
32 |
33 | /**
34 | *
35 | * @author joelauer (twitter: @jjlauer or http://twitter.com/jjlauer)
36 | */
37 | public class ParserMain {
38 | private static final Logger logger = LoggerFactory.getLogger(ParserMain.class);
39 |
40 | static public void main(String[] args) throws Exception {
41 | PduTranscoderContext context = new DefaultPduTranscoderContext();
42 | PduTranscoder transcoder = new DefaultPduTranscoder(context);
43 | ChannelBuffer buffer = BufferHelper.createBuffer("000000420000000400000000000000030001003633393238383032000101343439353133363139323035004000000000000000000774657374323232020B00020D05");
44 | Pdu pdu = transcoder.decode(buffer);
45 | logger.debug("{}", pdu);
46 | }
47 |
48 | }
49 |
--------------------------------------------------------------------------------
/src/test/java/com/cloudhopper/smpp/demo/SimulatorMain.java:
--------------------------------------------------------------------------------
1 | package com.cloudhopper.smpp.demo;
2 |
3 | /*
4 | * #%L
5 | * ch-smpp
6 | * %%
7 | * Copyright (C) 2009 - 2015 Cloudhopper by Twitter
8 | * %%
9 | * Licensed under the Apache License, Version 2.0 (the "License");
10 | * you may not use this file except in compliance with the License.
11 | * You may obtain a copy of the License at
12 | *
13 | * http://www.apache.org/licenses/LICENSE-2.0
14 | *
15 | * Unless required by applicable law or agreed to in writing, software
16 | * distributed under the License is distributed on an "AS IS" BASIS,
17 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18 | * See the License for the specific language governing permissions and
19 | * limitations under the License.
20 | * #L%
21 | */
22 |
23 | import com.cloudhopper.smpp.impl.DefaultSmppSessionHandler;
24 | import com.cloudhopper.smpp.pdu.PduRequest;
25 | import com.cloudhopper.smpp.pdu.PduResponse;
26 | import com.cloudhopper.smpp.simulator.SmppSimulatorServer;
27 | import com.cloudhopper.smpp.simulator.SmppSimulatorSessionHandler;
28 | import org.slf4j.Logger;
29 | import org.slf4j.LoggerFactory;
30 |
31 | /**
32 | *
33 | * @author joelauer (twitter: @jjlauer or http://twitter.com/jjlauer)
34 | */
35 | public class SimulatorMain {
36 | private static final Logger logger = LoggerFactory.getLogger(SimulatorMain.class);
37 |
38 | static public void main(String[] args) throws Exception {
39 | SmppSimulatorServer server = new SmppSimulatorServer();
40 | server.start(2776);
41 | logger.info("SMPP simulator server started");
42 |
43 | // wait for a session
44 | logger.info("Waiting for the first smsc session within 30 seconds");
45 | SmppSimulatorSessionHandler smscSession = server.pollNextSession(30000);
46 |
47 | logger.info("Successfully got an new session!");
48 |
49 | System.out.println("Press any key to shutdown simulator server");
50 | System.in.read();
51 |
52 | server.stop();
53 | }
54 |
55 | public static class SimulatorSmppSessionHandler extends DefaultSmppSessionHandler {
56 |
57 | public SimulatorSmppSessionHandler() {
58 | super(logger);
59 | }
60 |
61 | @Override
62 | public PduResponse firePduRequestReceived(PduRequest pduRequest) {
63 | // ignore for now (already logged)
64 | return pduRequest.createResponse();
65 | }
66 |
67 | }
68 |
69 | }
70 |
--------------------------------------------------------------------------------
/src/test/java/com/cloudhopper/smpp/demo/SlowServerMain.java:
--------------------------------------------------------------------------------
1 | package com.cloudhopper.smpp.demo;
2 |
3 | /*
4 | * #%L
5 | * ch-smpp
6 | * %%
7 | * Copyright (C) 2009 - 2015 Cloudhopper by Twitter
8 | * %%
9 | * Licensed under the Apache License, Version 2.0 (the "License");
10 | * you may not use this file except in compliance with the License.
11 | * You may obtain a copy of the License at
12 | *
13 | * http://www.apache.org/licenses/LICENSE-2.0
14 | *
15 | * Unless required by applicable law or agreed to in writing, software
16 | * distributed under the License is distributed on an "AS IS" BASIS,
17 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18 | * See the License for the specific language governing permissions and
19 | * limitations under the License.
20 | * #L%
21 | */
22 |
23 | import com.cloudhopper.smpp.SmppServer;
24 | import com.cloudhopper.smpp.SmppServerConfiguration;
25 | import com.cloudhopper.smpp.SmppServerHandler;
26 | import com.cloudhopper.smpp.SmppServerSession;
27 | import com.cloudhopper.smpp.SmppSessionConfiguration;
28 | import com.cloudhopper.smpp.impl.DefaultSmppServer;
29 | import com.cloudhopper.smpp.impl.DefaultSmppSessionHandler;
30 | import com.cloudhopper.smpp.pdu.BaseBind;
31 | import com.cloudhopper.smpp.pdu.BaseBindResp;
32 | import com.cloudhopper.smpp.pdu.PduRequest;
33 | import com.cloudhopper.smpp.pdu.PduResponse;
34 | import com.cloudhopper.smpp.type.SmppProcessingException;
35 | import org.slf4j.Logger;
36 | import org.slf4j.LoggerFactory;
37 |
38 | /**
39 | *
40 | * @author joelauer (twitter: @jjlauer or http://twitter.com/jjlauer)
41 | */
42 | public class SlowServerMain {
43 | private static final Logger logger = LoggerFactory.getLogger(SlowServerMain.class);
44 |
45 | private static final long DELAY_BEFORE_RESPONSE = 3000;
46 |
47 | static public void main(String[] args) throws Exception {
48 | SmppServerConfiguration configuration = new SmppServerConfiguration();
49 | configuration.setPort(2776);
50 | configuration.setMaxConnectionSize(10);
51 | configuration.setNonBlockingSocketsEnabled(false);
52 |
53 | SmppServer smppServer = new DefaultSmppServer(configuration, new DefaultSmppServerHandler());
54 |
55 | logger.info("About to start SMPP server");
56 | smppServer.start();
57 | logger.info("SMPP server started");
58 |
59 | System.out.println("Press any key to stop server");
60 | System.in.read();
61 |
62 | logger.info("SMPP server stopping");
63 | smppServer.stop();
64 | logger.info("SMPP server stopped");
65 | }
66 |
67 | public static class DefaultSmppServerHandler implements SmppServerHandler {
68 | @Override
69 | public void sessionBindRequested(Long sessionId, SmppSessionConfiguration sessionConfiguration, final BaseBind bindRequest) throws SmppProcessingException {
70 | // this name actually shows up as thread context....
71 | sessionConfiguration.setName("Application.SMPP." + sessionId);
72 | }
73 |
74 | @Override
75 | public void sessionCreated(Long sessionId, SmppServerSession session, BaseBindResp preparedBindResponse) throws SmppProcessingException {
76 | logger.info("Session created: {}", session);
77 | // need to do something it now (flag we're ready)
78 | session.serverReady(new SlowSmppSessionHandler());
79 | }
80 |
81 | @Override
82 | public void sessionDestroyed(Long sessionId, SmppServerSession session) {
83 | logger.info("Session destroyed: {}", session);
84 | }
85 |
86 | }
87 |
88 | public static class SlowSmppSessionHandler extends DefaultSmppSessionHandler {
89 | @Override
90 | public PduResponse firePduRequestReceived(PduRequest pduRequest) {
91 | try {
92 | Thread.sleep(DELAY_BEFORE_RESPONSE);
93 | } catch (Exception e) { }
94 |
95 | // ignore for now (already logged)
96 | return pduRequest.createResponse();
97 | }
98 | }
99 |
100 | }
101 |
--------------------------------------------------------------------------------
/src/test/java/com/cloudhopper/smpp/demo/persist/Client.java:
--------------------------------------------------------------------------------
1 | package com.cloudhopper.smpp.demo.persist;
2 |
3 | /*
4 | * #%L
5 | * ch-smpp
6 | * %%
7 | * Copyright (C) 2009 - 2014 Cloudhopper by Twitter
8 | * %%
9 | * Licensed under the Apache License, Version 2.0 (the "License");
10 | * you may not use this file except in compliance with the License.
11 | * You may obtain a copy of the License at
12 | *
13 | * http://www.apache.org/licenses/LICENSE-2.0
14 | *
15 | * Unless required by applicable law or agreed to in writing, software
16 | * distributed under the License is distributed on an "AS IS" BASIS,
17 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18 | * See the License for the specific language governing permissions and
19 | * limitations under the License.
20 | * #L%
21 | */
22 |
23 | import com.cloudhopper.smpp.SmppSession;
24 | import com.cloudhopper.smpp.SmppSessionConfiguration;
25 |
26 | public abstract class Client {
27 |
28 | protected volatile SmppSession smppSession;
29 |
30 | public SmppSessionConfiguration getConfiguration() {
31 | return smppSession.getConfiguration();
32 | }
33 |
34 | public boolean isConnected() {
35 | SmppSession session = smppSession;
36 | if (session != null) {
37 | return session.isBound();
38 | }
39 | return false;
40 | }
41 |
42 | public SmppSession getSession() {
43 | return smppSession;
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/src/test/java/com/cloudhopper/smpp/demo/persist/ClientSmppSessionHandler.java:
--------------------------------------------------------------------------------
1 | package com.cloudhopper.smpp.demo.persist;
2 |
3 | /*
4 | * #%L
5 | * ch-smpp
6 | * %%
7 | * Copyright (C) 2009 - 2014 Cloudhopper by Twitter
8 | * %%
9 | * Licensed under the Apache License, Version 2.0 (the "License");
10 | * you may not use this file except in compliance with the License.
11 | * You may obtain a copy of the License at
12 | *
13 | * http://www.apache.org/licenses/LICENSE-2.0
14 | *
15 | * Unless required by applicable law or agreed to in writing, software
16 | * distributed under the License is distributed on an "AS IS" BASIS,
17 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18 | * See the License for the specific language governing permissions and
19 | * limitations under the License.
20 | * #L%
21 | */
22 |
23 |
24 | import com.cloudhopper.smpp.SmppConstants;
25 | import com.cloudhopper.smpp.impl.DefaultSmppSessionHandler;
26 | import com.cloudhopper.smpp.pdu.*;
27 | import org.slf4j.Logger;
28 | import org.slf4j.LoggerFactory;
29 |
30 | import java.io.IOException;
31 | import java.nio.channels.ClosedChannelException;
32 |
33 | public class ClientSmppSessionHandler extends DefaultSmppSessionHandler {
34 |
35 | private static final Logger logger = LoggerFactory.getLogger(ClientSmppSessionHandler.class);
36 |
37 | private OutboundClient client;
38 | private SmppClientMessageService smppClientMessageService;
39 |
40 | public ClientSmppSessionHandler(OutboundClient client,
41 | SmppClientMessageService smppClientMessageService) {
42 | super(logger);
43 | this.client = client;
44 | this.smppClientMessageService = smppClientMessageService;
45 | }
46 |
47 | @Override
48 | public void firePduRequestExpired(PduRequest pduRequest) {
49 | logger.warn("PDU request expired: {}", pduRequest);
50 | }
51 |
52 | @Override
53 | public PduResponse firePduRequestReceived(PduRequest request) {
54 | PduResponse response = null;
55 | try {
56 | if (request instanceof DeliverSm) {
57 | logger.info("request {}", request);
58 | response = smppClientMessageService.received(client, (DeliverSm) request);
59 | logger.info("response {}", response);
60 | } else {
61 | response = request.createResponse();
62 | }
63 | } catch (Throwable e) {
64 | LoggingUtil.log(logger, e);
65 | response = request.createResponse();
66 | response.setResultMessage(e.getMessage());
67 | response.setCommandStatus(SmppConstants.STATUS_UNKNOWNERR);
68 | }
69 |
70 | return response;
71 | }
72 |
73 | /**
74 | * TODO not sure if we really need to call reconnect here
75 | */
76 | @Override
77 | public void fireUnknownThrowable(Throwable t) {
78 | if (t instanceof ClosedChannelException) {
79 | logger.warn("Unknown throwable received, but it was a ClosedChannelException, executing reconnect" + " "
80 | + LoggingUtil.toString(client.getConfiguration()));
81 | client.scheduleReconnect();
82 | } else if (t instanceof IOException) {
83 | logger.warn(t + " " + LoggingUtil.toString(client.getConfiguration()));
84 | //#fireChannelUnexpectedlyClosed will be called from a different place
85 | } else {
86 | logger.warn(String.valueOf(t) + " " + LoggingUtil.toString(client.getConfiguration()), t);
87 | }
88 | }
89 |
90 | @Override
91 | public void fireChannelUnexpectedlyClosed() {
92 | client.scheduleReconnect();
93 | }
94 |
95 | }
96 |
--------------------------------------------------------------------------------
/src/test/java/com/cloudhopper/smpp/demo/persist/DummySmppClientMessageService.java:
--------------------------------------------------------------------------------
1 | package com.cloudhopper.smpp.demo.persist;
2 |
3 | /*
4 | * #%L
5 | * ch-smpp
6 | * %%
7 | * Copyright (C) 2009 - 2014 Cloudhopper by Twitter
8 | * %%
9 | * Licensed under the Apache License, Version 2.0 (the "License");
10 | * you may not use this file except in compliance with the License.
11 | * You may obtain a copy of the License at
12 | *
13 | * http://www.apache.org/licenses/LICENSE-2.0
14 | *
15 | * Unless required by applicable law or agreed to in writing, software
16 | * distributed under the License is distributed on an "AS IS" BASIS,
17 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18 | * See the License for the specific language governing permissions and
19 | * limitations under the License.
20 | * #L%
21 | */
22 |
23 |
24 | import com.cloudhopper.smpp.pdu.DeliverSm;
25 | import com.cloudhopper.smpp.pdu.PduResponse;
26 |
27 | public class DummySmppClientMessageService implements SmppClientMessageService {
28 |
29 | /** delivery receipt, or MO */
30 | @Override
31 | public PduResponse received(OutboundClient client, DeliverSm deliverSm) {
32 | return deliverSm.createResponse();
33 | }
34 |
35 | }
36 |
--------------------------------------------------------------------------------
/src/test/java/com/cloudhopper/smpp/demo/persist/EnquireLinkTask.java:
--------------------------------------------------------------------------------
1 | package com.cloudhopper.smpp.demo.persist;
2 |
3 | /*
4 | * #%L
5 | * ch-smpp
6 | * %%
7 | * Copyright (C) 2009 - 2014 Cloudhopper by Twitter
8 | * %%
9 | * Licensed under the Apache License, Version 2.0 (the "License");
10 | * you may not use this file except in compliance with the License.
11 | * You may obtain a copy of the License at
12 | *
13 | * http://www.apache.org/licenses/LICENSE-2.0
14 | *
15 | * Unless required by applicable law or agreed to in writing, software
16 | * distributed under the License is distributed on an "AS IS" BASIS,
17 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18 | * See the License for the specific language governing permissions and
19 | * limitations under the License.
20 | * #L%
21 | */
22 |
23 | import com.cloudhopper.smpp.SmppSession;
24 | import com.cloudhopper.smpp.pdu.EnquireLink;
25 | import com.cloudhopper.smpp.pdu.EnquireLinkResp;
26 | import com.cloudhopper.smpp.type.SmppChannelException;
27 | import com.cloudhopper.smpp.type.SmppTimeoutException;
28 | import org.slf4j.Logger;
29 | import org.slf4j.LoggerFactory;
30 |
31 | class EnquireLinkTask implements Runnable {
32 |
33 | private static final Logger logger = LoggerFactory.getLogger(EnquireLinkTask.class);
34 | private OutboundClient client;
35 | private Integer enquireLinkTimeout;
36 |
37 | public EnquireLinkTask(OutboundClient client, Integer enquireLinkTimeout) {
38 | this.client = client;
39 | this.enquireLinkTimeout = enquireLinkTimeout;
40 | }
41 |
42 | @Override
43 | public void run() {
44 | SmppSession smppSession = client.getSession();
45 | if (smppSession != null && smppSession.isBound()) {
46 | try {
47 | logger.debug("sending enquire_link");
48 | EnquireLinkResp enquireLinkResp = smppSession.enquireLink(new EnquireLink(), enquireLinkTimeout);
49 | logger.debug("enquire_link_resp: {}", enquireLinkResp);
50 | } catch (SmppTimeoutException e) {
51 | logger.warn("Enquire link failed, executing reconnect; " + e);
52 | logger.debug("", e);
53 | client.scheduleReconnect();
54 | } catch (SmppChannelException e) {
55 | logger.warn("Enquire link failed, executing reconnect; " + e);
56 | logger.debug("", e);
57 | client.scheduleReconnect();
58 | } catch (InterruptedException e) {
59 | logger.info("Enquire link interrupted, probably killed by reconnecting");
60 | } catch (Exception e) {
61 | logger.error("Enquire link failed, executing reconnect", e);
62 | client.scheduleReconnect();
63 | }
64 | } else {
65 | logger.error("enquire link running while session is not connected");
66 | }
67 | }
68 | }
69 |
--------------------------------------------------------------------------------
/src/test/java/com/cloudhopper/smpp/demo/persist/LoggingUtil.java:
--------------------------------------------------------------------------------
1 | package com.cloudhopper.smpp.demo.persist;
2 |
3 | /*
4 | * #%L
5 | * ch-smpp
6 | * %%
7 | * Copyright (C) 2009 - 2014 Cloudhopper by Twitter
8 | * %%
9 | * Licensed under the Apache License, Version 2.0 (the "License");
10 | * you may not use this file except in compliance with the License.
11 | * You may obtain a copy of the License at
12 | *
13 | * http://www.apache.org/licenses/LICENSE-2.0
14 | *
15 | * Unless required by applicable law or agreed to in writing, software
16 | * distributed under the License is distributed on an "AS IS" BASIS,
17 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18 | * See the License for the specific language governing permissions and
19 | * limitations under the License.
20 | * #L%
21 | */
22 |
23 |
24 | import org.slf4j.Logger;
25 |
26 | import com.cloudhopper.smpp.SmppSessionConfiguration;
27 |
28 | public class LoggingUtil {
29 |
30 | public static String toString(SmppSessionConfiguration config) {
31 | StringBuilder sb = new StringBuilder();
32 | sb.append("[");
33 | sb.append(config.getSystemId());
34 | sb.append(":");
35 | sb.append(config.getPassword());
36 |
37 | sb.append(";");
38 |
39 | sb.append(config.getHost());
40 | sb.append(":");
41 | sb.append(config.getPort());
42 |
43 | sb.append(";");
44 | sb.append(config.getType());
45 | sb.append("]");
46 | return sb.toString();
47 | }
48 |
49 | public static String toString2(SmppSessionConfiguration config) {
50 | StringBuilder sb = new StringBuilder();
51 | sb.append("[");
52 |
53 | sb.append(config.getName());
54 |
55 | sb.append(";");
56 |
57 | sb.append(config.getSystemId());
58 |
59 | sb.append(";");
60 |
61 | sb.append(config.getHost());
62 | sb.append(":");
63 | sb.append(config.getPort());
64 |
65 | sb.append(";");
66 | sb.append(config.getType());
67 | sb.append("]");
68 | return sb.toString();
69 | }
70 |
71 | public static void log(Logger log, Throwable e) {
72 | log.warn(String.valueOf(e.getMessage()), e);
73 | }
74 | }
75 |
--------------------------------------------------------------------------------
/src/test/java/com/cloudhopper/smpp/demo/persist/ReconnectionDaemon.java:
--------------------------------------------------------------------------------
1 | package com.cloudhopper.smpp.demo.persist;
2 |
3 | /*
4 | * #%L
5 | * ch-smpp
6 | * %%
7 | * Copyright (C) 2009 - 2014 Cloudhopper by Twitter
8 | * %%
9 | * Licensed under the Apache License, Version 2.0 (the "License");
10 | * you may not use this file except in compliance with the License.
11 | * You may obtain a copy of the License at
12 | *
13 | * http://www.apache.org/licenses/LICENSE-2.0
14 | *
15 | * Unless required by applicable law or agreed to in writing, software
16 | * distributed under the License is distributed on an "AS IS" BASIS,
17 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18 | * See the License for the specific language governing permissions and
19 | * limitations under the License.
20 | * #L%
21 | */
22 |
23 | import org.slf4j.Logger;
24 | import org.slf4j.LoggerFactory;
25 |
26 | import javax.annotation.PreDestroy;
27 | import java.util.concurrent.*;
28 | import java.util.concurrent.atomic.AtomicInteger;
29 |
30 | /**
31 | * #schedule cannot spawn more threads than corePoolSize, so the blocking work is done by separate executor
32 | */
33 | public class ReconnectionDaemon {
34 |
35 | private static final Logger log = LoggerFactory.getLogger(ReconnectionDaemon.class);
36 |
37 | private static final ReconnectionDaemon RECONNECTION_DAEMON = new ReconnectionDaemon("0,5,15");
38 | private static final long KEEP_ALIVE_TIME = 60L;
39 |
40 | private final String[] reconnectionPeriods;
41 |
42 | private final ThreadPoolExecutor executor;
43 | private final ScheduledExecutorService scheduledExecutorService;
44 |
45 | public ReconnectionDaemon(String reconnectionPeriods) {
46 | this.reconnectionPeriods = reconnectionPeriods.split(",");
47 | scheduledExecutorService = Executors.newSingleThreadScheduledExecutor(getThreadFactory("ReconnectionSchedulerDaemon-"));
48 |
49 | executor = new ThreadPoolExecutor(0, Integer.MAX_VALUE, KEEP_ALIVE_TIME, TimeUnit.SECONDS,
50 | new SynchronousQueue(), getThreadFactory("ReconnectionExecutorDaemon-"));
51 | }
52 |
53 | private ThreadFactory getThreadFactory(final String name) {
54 | return new ThreadFactory() {
55 |
56 | private AtomicInteger sequence = new AtomicInteger(0);
57 |
58 | @Override
59 | public Thread newThread(Runnable r) {
60 | Thread t = new Thread(r);
61 | t.setName(name + sequence.getAndIncrement());
62 | return t;
63 | }
64 | };
65 | }
66 |
67 | public static ReconnectionDaemon getInstance() {
68 | return RECONNECTION_DAEMON;
69 | }
70 |
71 | public void scheduleReconnect(OutboundClient outboundClient, Integer failureCount,
72 | ReconnectionTask reconnectionTask) {
73 | long delay = getReconnectionPeriod(failureCount);
74 | log.info("Scheduling reconnect for {} in {} seconds", outboundClient, delay);
75 | scheduledExecutorService.schedule(new ScheduledTask(reconnectionTask), delay,
76 | TimeUnit.SECONDS);
77 | }
78 |
79 | private long getReconnectionPeriod(Integer failureCount) {
80 | String reconnectionPeriod;
81 | if (reconnectionPeriods.length > failureCount) {
82 | reconnectionPeriod = reconnectionPeriods[failureCount];
83 | } else {
84 | reconnectionPeriod = reconnectionPeriods[reconnectionPeriods.length - 1];
85 | }
86 | return Long.parseLong(reconnectionPeriod);
87 | }
88 |
89 | @PreDestroy
90 | public void shutdown() {
91 | executor.shutdown();
92 | scheduledExecutorService.shutdown();
93 | }
94 |
95 | private class ScheduledTask implements Runnable {
96 |
97 | private final Runnable task;
98 |
99 | public ScheduledTask(Runnable task) {
100 | this.task = task;
101 | }
102 |
103 | @Override
104 | public void run() {
105 | executor.execute(task);
106 | }
107 | }
108 | }
109 |
--------------------------------------------------------------------------------
/src/test/java/com/cloudhopper/smpp/demo/persist/ReconnectionTask.java:
--------------------------------------------------------------------------------
1 | package com.cloudhopper.smpp.demo.persist;
2 |
3 | /*
4 | * #%L
5 | * ch-smpp
6 | * %%
7 | * Copyright (C) 2009 - 2014 Cloudhopper by Twitter
8 | * %%
9 | * Licensed under the Apache License, Version 2.0 (the "License");
10 | * you may not use this file except in compliance with the License.
11 | * You may obtain a copy of the License at
12 | *
13 | * http://www.apache.org/licenses/LICENSE-2.0
14 | *
15 | * Unless required by applicable law or agreed to in writing, software
16 | * distributed under the License is distributed on an "AS IS" BASIS,
17 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18 | * See the License for the specific language governing permissions and
19 | * limitations under the License.
20 | * #L%
21 | */
22 |
23 | public class ReconnectionTask implements Runnable {
24 |
25 | private final OutboundClient client;
26 | private Integer connectionFailedTimes;
27 |
28 | protected ReconnectionTask(OutboundClient client, Integer connectionFailedTimes) {
29 | this.client = client;
30 | this.connectionFailedTimes = connectionFailedTimes;
31 | }
32 |
33 | @Override
34 | public void run() {
35 | client.reconnect(connectionFailedTimes);
36 | }
37 |
38 | }
39 |
--------------------------------------------------------------------------------
/src/test/java/com/cloudhopper/smpp/demo/persist/SmppClientMessageService.java:
--------------------------------------------------------------------------------
1 | package com.cloudhopper.smpp.demo.persist;
2 |
3 | /*
4 | * #%L
5 | * ch-smpp
6 | * %%
7 | * Copyright (C) 2009 - 2014 Cloudhopper by Twitter
8 | * %%
9 | * Licensed under the Apache License, Version 2.0 (the "License");
10 | * you may not use this file except in compliance with the License.
11 | * You may obtain a copy of the License at
12 | *
13 | * http://www.apache.org/licenses/LICENSE-2.0
14 | *
15 | * Unless required by applicable law or agreed to in writing, software
16 | * distributed under the License is distributed on an "AS IS" BASIS,
17 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18 | * See the License for the specific language governing permissions and
19 | * limitations under the License.
20 | * #L%
21 | */
22 |
23 |
24 | import com.cloudhopper.smpp.pdu.DeliverSm;
25 | import com.cloudhopper.smpp.pdu.PduResponse;
26 |
27 | public interface SmppClientMessageService {
28 |
29 | PduResponse received(OutboundClient client, DeliverSm deliverSm);
30 | }
31 |
--------------------------------------------------------------------------------
/src/test/java/com/cloudhopper/smpp/pdu/BufferHelper.java:
--------------------------------------------------------------------------------
1 | package com.cloudhopper.smpp.pdu;
2 |
3 | /*
4 | * #%L
5 | * ch-smpp
6 | * %%
7 | * Copyright (C) 2009 - 2015 Cloudhopper by Twitter
8 | * %%
9 | * Licensed under the Apache License, Version 2.0 (the "License");
10 | * you may not use this file except in compliance with the License.
11 | * You may obtain a copy of the License at
12 | *
13 | * http://www.apache.org/licenses/LICENSE-2.0
14 | *
15 | * Unless required by applicable law or agreed to in writing, software
16 | * distributed under the License is distributed on an "AS IS" BASIS,
17 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18 | * See the License for the specific language governing permissions and
19 | * limitations under the License.
20 | * #L%
21 | */
22 |
23 | import com.cloudhopper.commons.util.HexUtil;
24 | import org.jboss.netty.buffer.BigEndianHeapChannelBuffer;
25 | import org.jboss.netty.buffer.ChannelBuffer;
26 |
27 | /**
28 | *
29 | * @author joelauer (twitter: @jjlauer or http://twitter.com/jjlauer)
30 | */
31 | public class BufferHelper
32 | {
33 |
34 | static public ChannelBuffer createBuffer(byte[] bytes) throws Exception {
35 | return new BigEndianHeapChannelBuffer(bytes);
36 | }
37 |
38 | static public ChannelBuffer createBuffer(String hexString) throws Exception {
39 | return createBuffer(HexUtil.toByteArray(hexString));
40 | }
41 |
42 | static public byte[] createByteArray(ChannelBuffer buffer) throws Exception {
43 | byte[] bytes = new byte[buffer.readableBytes()];
44 | // temporarily read bytes from the buffer
45 | buffer.getBytes(buffer.readerIndex(), bytes);
46 | return bytes;
47 | }
48 |
49 | static public String createHexString(ChannelBuffer buffer) throws Exception {
50 | return HexUtil.toHexString(createByteArray(buffer));
51 | }
52 |
53 | }
54 |
--------------------------------------------------------------------------------
/src/test/java/com/cloudhopper/smpp/pdu/PduTest.java:
--------------------------------------------------------------------------------
1 | package com.cloudhopper.smpp.pdu;
2 |
3 | /*
4 | * #%L
5 | * ch-smpp
6 | * %%
7 | * Copyright (C) 2009 - 2015 Cloudhopper by Twitter
8 | * %%
9 | * Licensed under the Apache License, Version 2.0 (the "License");
10 | * you may not use this file except in compliance with the License.
11 | * You may obtain a copy of the License at
12 | *
13 | * http://www.apache.org/licenses/LICENSE-2.0
14 | *
15 | * Unless required by applicable law or agreed to in writing, software
16 | * distributed under the License is distributed on an "AS IS" BASIS,
17 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18 | * See the License for the specific language governing permissions and
19 | * limitations under the License.
20 | * #L%
21 | */
22 |
23 | // third party imports
24 | import org.junit.*;
25 | import org.slf4j.Logger;
26 | import org.slf4j.LoggerFactory;
27 |
28 | // my imports
29 |
30 | /**
31 | *
32 | * @author joelauer (twitter: @jjlauer or http://twitter.com/jjlauer)
33 | */
34 | public class PduTest {
35 | private static final Logger logger = LoggerFactory.getLogger(PduTest.class);
36 |
37 | @Test
38 | public void hasSequenceNumberAssigned() throws Exception {
39 | Pdu pdu0 = new EnquireLink();
40 |
41 | Assert.assertEquals(false, pdu0.hasSequenceNumberAssigned());
42 |
43 | pdu0.setSequenceNumber(0);
44 |
45 | Assert.assertEquals(true, pdu0.hasSequenceNumberAssigned());
46 |
47 | pdu0.removeSequenceNumber();
48 |
49 | Assert.assertEquals(false, pdu0.hasSequenceNumberAssigned());
50 | Assert.assertEquals(0, pdu0.getSequenceNumber());
51 | }
52 |
53 | @Test
54 | public void hasCommandLengthCalculatedAndSet() throws Exception {
55 | Pdu pdu0 = new EnquireLink();
56 |
57 | Assert.assertEquals(false, pdu0.hasCommandLengthCalculated());
58 | Assert.assertEquals(16, pdu0.calculateAndSetCommandLength());
59 | Assert.assertEquals(true, pdu0.hasCommandLengthCalculated());
60 | Assert.assertEquals(16, pdu0.getCommandLength());
61 | }
62 | }
63 |
--------------------------------------------------------------------------------
/src/test/java/com/cloudhopper/smpp/ssl/SslContextFactoryTest.java:
--------------------------------------------------------------------------------
1 | package com.cloudhopper.smpp.ssl;
2 |
3 | /*
4 | * #%L
5 | * ch-smpp
6 | * %%
7 | * Copyright (C) 2009 - 2013 Cloudhopper by Twitter
8 | * %%
9 | * Licensed under the Apache License, Version 2.0 (the "License");
10 | * you may not use this file except in compliance with the License.
11 | * You may obtain a copy of the License at
12 | *
13 | * http://www.apache.org/licenses/LICENSE-2.0
14 | *
15 | * Unless required by applicable law or agreed to in writing, software
16 | * distributed under the License is distributed on an "AS IS" BASIS,
17 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18 | * See the License for the specific language governing permissions and
19 | * limitations under the License.
20 | * #L%
21 | */
22 |
23 | import java.io.IOException;
24 | import java.io.InputStream;
25 | import java.security.KeyStore;
26 | import java.security.UnrecoverableKeyException;
27 | import org.junit.Assert;
28 | import org.junit.Test;
29 |
30 | public class SslContextFactoryTest {
31 |
32 | @Test
33 | public void testNoTsFileKs() throws Exception {
34 | SslConfiguration cf = new SslConfiguration();
35 | cf.setKeyStorePath("src/test/resources/keystore");
36 | cf.setKeyStorePassword("changeit");
37 | cf.setKeyManagerPassword("changeit");
38 | SslContextFactory factory = new SslContextFactory(cf);
39 | Assert.assertTrue(factory.getSslContext() != null);
40 | }
41 |
42 | @Test
43 | public void testNoTsNoKs() throws Exception {
44 | SslConfiguration cf = new SslConfiguration();
45 | SslContextFactory factory = new SslContextFactory(cf);
46 | Assert.assertTrue(factory.getSslContext() != null);
47 | }
48 |
49 | @Test
50 | public void testFileTsFileKs() throws Exception {
51 | SslConfiguration cf = new SslConfiguration();
52 | cf.setKeyStorePath("src/test/resources/keystore");
53 | cf.setKeyStorePassword("changeit");
54 | cf.setKeyManagerPassword("changeit");
55 | cf.setTrustStorePath("src/test/resources/keystore");
56 | cf.setTrustStorePassword("changeit");
57 | SslContextFactory factory = new SslContextFactory(cf);
58 | Assert.assertTrue(factory.getSslContext() != null);
59 | }
60 |
61 | @Test
62 | public void testFileTsFileKsWrongPW() throws Exception {
63 | SslConfiguration cf = new SslConfiguration();
64 | cf.setKeyStorePath("src/test/resources/keystore");
65 | cf.setKeyStorePassword("bad_password");
66 | cf.setKeyManagerPassword("changeit");
67 | cf.setTrustStorePath("src/test/resources/keystore");
68 | cf.setTrustStorePassword("changeit");
69 | try {
70 | SslContextFactory factory = new SslContextFactory(cf);
71 | Assert.fail();
72 | } catch(IOException e) {
73 | }
74 | }
75 |
76 | @Test
77 | public void testPathTsWrongPWPathKs() throws Exception {
78 | SslConfiguration cf = new SslConfiguration();
79 | cf.setKeyStorePath("src/test/resources/keystore");
80 | cf.setKeyStorePassword("changeit");
81 | cf.setKeyManagerPassword("changeit");
82 | cf.setTrustStorePath("src/test/resources/keystore");
83 | cf.setTrustStorePassword("bad_password");
84 | try {
85 | SslContextFactory factory = new SslContextFactory(cf);
86 | Assert.fail();
87 | } catch(IOException e) {
88 | }
89 | }
90 |
91 | @Test
92 | public void testNoKeyConfig() throws Exception {
93 | try {
94 | SslConfiguration cf = new SslConfiguration();
95 | cf.setTrustStorePath("src/test/resources/keystore");
96 | SslContextFactory factory = new SslContextFactory(cf);
97 | Assert.fail();
98 | } catch (IllegalStateException e) {
99 | } catch (Exception e) {
100 | Assert.fail("Unexpected exception");
101 | }
102 | }
103 |
104 | }
105 |
--------------------------------------------------------------------------------
/src/test/java/com/cloudhopper/smpp/util/ConcurrentCommandStatusCounterTest.java:
--------------------------------------------------------------------------------
1 | package com.cloudhopper.smpp.util;
2 | /*
3 | * #%L
4 | * ch-smpp
5 | * %%
6 | * Copyright (C) 2009 - 2015 Cloudhopper by Twitter
7 | * %%
8 | * Licensed under the Apache License, Version 2.0 (the "License");
9 | * you may not use this file except in compliance with the License.
10 | * You may obtain a copy of the License at
11 | *
12 | * http://www.apache.org/licenses/LICENSE-2.0
13 | *
14 | * Unless required by applicable law or agreed to in writing, software
15 | * distributed under the License is distributed on an "AS IS" BASIS,
16 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 | * See the License for the specific language governing permissions and
18 | * limitations under the License.
19 | * #L%
20 | */
21 |
22 | import com.cloudhopper.smpp.SmppConstants;
23 | import org.junit.Test;
24 | import static org.junit.Assert.assertEquals;
25 |
26 | /**
27 | *
28 | * @author Maria Farooq
29 | */
30 | public class ConcurrentCommandStatusCounterTest {
31 |
32 | @Test
33 | public void incrementAndGetTest (){
34 | ConcurrentCommandStatusCounter concurrentCommandStatusCounter = new ConcurrentCommandStatusCounter();
35 | assertEquals(0, concurrentCommandStatusCounter.getClientErrorCounter().intValue());
36 | assertEquals(0, concurrentCommandStatusCounter.getClientErrorCounter().intValue());
37 |
38 | concurrentCommandStatusCounter.incrementAndGet(SmppConstants.STATUS_OK);
39 | assertEquals(0, concurrentCommandStatusCounter.getClientErrorCounter().intValue());
40 | assertEquals(0, concurrentCommandStatusCounter.getClientErrorCounter().intValue());
41 |
42 |
43 | concurrentCommandStatusCounter.incrementAndGet(SmppConstants.STATUS_INVDSTADR);
44 | assertEquals(1, concurrentCommandStatusCounter.getClientErrorCounter().intValue());
45 | assertEquals(0, concurrentCommandStatusCounter.getServerErrorCounter().intValue());
46 |
47 |
48 | concurrentCommandStatusCounter.incrementAndGet(SmppConstants.STATUS_INVSYSID);
49 | assertEquals(1, concurrentCommandStatusCounter.getClientErrorCounter().intValue());
50 | assertEquals(1, concurrentCommandStatusCounter.getServerErrorCounter().intValue());
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/src/test/java/com/cloudhopper/smpp/util/SequenceNumberTest.java:
--------------------------------------------------------------------------------
1 | package com.cloudhopper.smpp.util;
2 |
3 | /*
4 | * #%L
5 | * ch-smpp
6 | * %%
7 | * Copyright (C) 2009 - 2015 Cloudhopper by Twitter
8 | * %%
9 | * Licensed under the Apache License, Version 2.0 (the "License");
10 | * you may not use this file except in compliance with the License.
11 | * You may obtain a copy of the License at
12 | *
13 | * http://www.apache.org/licenses/LICENSE-2.0
14 | *
15 | * Unless required by applicable law or agreed to in writing, software
16 | * distributed under the License is distributed on an "AS IS" BASIS,
17 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18 | * See the License for the specific language governing permissions and
19 | * limitations under the License.
20 | * #L%
21 | */
22 |
23 | // third party imports
24 | import org.junit.*;
25 |
26 | // my imports
27 |
28 | /**
29 | *
30 | * @author joelauer (twitter: @jjlauer or http://twitter.com/jjlauer)
31 | */
32 | public class SequenceNumberTest {
33 |
34 | @Test
35 | public void usage() throws Exception {
36 | SequenceNumber seqNum = new SequenceNumber();
37 | Assert.assertEquals(1, seqNum.next());
38 | Assert.assertEquals(2, seqNum.next());
39 | Assert.assertEquals(3, seqNum.next());
40 | Assert.assertEquals(4, seqNum.next());
41 |
42 | seqNum = new SequenceNumber(0x7FFFFFFF);
43 | Assert.assertEquals(0x7FFFFFFF, seqNum.next());
44 | Assert.assertEquals(1, seqNum.next()); // wrap around
45 | Assert.assertEquals(2, seqNum.next());
46 | Assert.assertEquals(3, seqNum.next());
47 |
48 | Assert.assertEquals(4, seqNum.peek());
49 |
50 | seqNum.reset();
51 |
52 | Assert.assertEquals(1, seqNum.peek());
53 | Assert.assertEquals(1, seqNum.next());
54 | Assert.assertEquals(2, seqNum.next());
55 | Assert.assertEquals(3, seqNum.next());
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/src/test/java/com/cloudhopper/smpp/util/TlvUtilTest.java:
--------------------------------------------------------------------------------
1 | package com.cloudhopper.smpp.util;
2 |
3 | /*
4 | * #%L
5 | * ch-smpp
6 | * %%
7 | * Copyright (C) 2009 - 2015 Cloudhopper by Twitter
8 | * %%
9 | * Licensed under the Apache License, Version 2.0 (the "License");
10 | * you may not use this file except in compliance with the License.
11 | * You may obtain a copy of the License at
12 | *
13 | * http://www.apache.org/licenses/LICENSE-2.0
14 | *
15 | * Unless required by applicable law or agreed to in writing, software
16 | * distributed under the License is distributed on an "AS IS" BASIS,
17 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18 | * See the License for the specific language governing permissions and
19 | * limitations under the License.
20 | * #L%
21 | */
22 |
23 | // third party imports
24 | import com.cloudhopper.commons.util.HexUtil;
25 | import com.cloudhopper.smpp.tlv.Tlv;
26 | import com.cloudhopper.smpp.tlv.TlvConvertException;
27 | import org.junit.*;
28 | import org.slf4j.Logger;
29 | import org.slf4j.LoggerFactory;
30 |
31 | // my imports
32 |
33 | /**
34 | *
35 | * @author joelauer (twitter: @jjlauer or http://twitter.com/jjlauer)
36 | */
37 | public class TlvUtilTest {
38 | private static final Logger logger = LoggerFactory.getLogger(TlvUtilTest.class);
39 |
40 | @Test
41 | public void createNullTerminatedStringTlv() throws Exception {
42 | Tlv tlv0 = null;
43 |
44 | // null string should just be 0x00
45 | tlv0 = TlvUtil.createNullTerminatedStringTlv((short)0x0001, null, "ISO-8859-1");
46 | Assert.assertEquals((short)0x0001, tlv0.getTag());
47 | Assert.assertArrayEquals(HexUtil.toByteArray("00"), tlv0.getValue());
48 |
49 | tlv0 = TlvUtil.createNullTerminatedStringTlv((short)0x0001, "", "ISO-8859-1");
50 | Assert.assertEquals((short)0x0001, tlv0.getTag());
51 | Assert.assertArrayEquals(HexUtil.toByteArray("00"), tlv0.getValue());
52 |
53 | tlv0 = TlvUtil.createNullTerminatedStringTlv((short)0x0001, "a");
54 | Assert.assertEquals((short)0x0001, tlv0.getTag());
55 | Assert.assertArrayEquals(HexUtil.toByteArray("6100"), tlv0.getValue());
56 |
57 | tlv0 = TlvUtil.createNullTerminatedStringTlv((short)0x0001, "c1net");
58 | Assert.assertEquals((short)0x0001, tlv0.getTag());
59 | Assert.assertArrayEquals(HexUtil.toByteArray("63316e657400"), tlv0.getValue());
60 | }
61 |
62 | @Test
63 | public void createFixedLengthStringTlv() throws Exception {
64 | Tlv tlv0 = null;
65 |
66 | tlv0 = TlvUtil.createFixedLengthStringTlv((short)0x0001, null, 2, "ISO-8859-1");
67 | Assert.assertEquals((short)0x0001, tlv0.getTag());
68 | Assert.assertArrayEquals(HexUtil.toByteArray("0000"), tlv0.getValue());
69 |
70 | tlv0 = TlvUtil.createFixedLengthStringTlv((short)0x0001, "", 2);
71 | Assert.assertEquals((short)0x0001, tlv0.getTag());
72 | Assert.assertArrayEquals(HexUtil.toByteArray("0000"), tlv0.getValue());
73 |
74 | tlv0 = TlvUtil.createFixedLengthStringTlv((short)0x0001, "1", 2, "ISO-8859-1");
75 | Assert.assertEquals((short)0x0001, tlv0.getTag());
76 | Assert.assertArrayEquals(HexUtil.toByteArray("3100"), tlv0.getValue());
77 |
78 | tlv0 = TlvUtil.createFixedLengthStringTlv((short)0x0001, "12", 2);
79 | Assert.assertEquals((short)0x0001, tlv0.getTag());
80 | Assert.assertArrayEquals(HexUtil.toByteArray("3132"), tlv0.getValue());
81 |
82 | try {
83 | tlv0 = TlvUtil.createFixedLengthStringTlv((short)0x0001, "12", 1, "ISO-8859-1");
84 | Assert.fail();
85 | } catch (TlvConvertException e) {
86 | // correct behavior
87 | }
88 | }
89 | }
90 |
--------------------------------------------------------------------------------
/src/test/resources/keystore:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RestComm/cloudhopper-smpp/99a45b7e9389c79566a369f0f1d7902f20027353/src/test/resources/keystore
--------------------------------------------------------------------------------
/src/test/resources/logback-test.xml:
--------------------------------------------------------------------------------
1 |
2 |
21 |
22 |
23 |
24 | System.err
25 |
26 | %-23d [%thread] %-5level %logger{32} - %m%n
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
--------------------------------------------------------------------------------
/src/test/resources/server.crt:
--------------------------------------------------------------------------------
1 | -----BEGIN CERTIFICATE-----
2 | MIICATCCAWoCCQCEwdEo1Uc29TANBgkqhkiG9w0BAQUFADBFMQswCQYDVQQGEwJB
3 | VTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50ZXJuZXQgV2lkZ2l0
4 | cyBQdHkgTHRkMB4XDTEzMDQxMDIzNTI1M1oXDTE0MDQxMDIzNTI1M1owRTELMAkG
5 | A1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoMGEludGVybmV0
6 | IFdpZGdpdHMgUHR5IEx0ZDCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAs9ao
7 | eqfWIKjMQ+hggOclu6/zftOrvoCcZ8HYoE5G2YOQuvT2zIcTDR5EHcMuhlkF/5SV
8 | ta4baG6EZdO/WE3sJcVjJ64/5gBAXAOzw+f/pNoPyEGnFzpJugKemy0WntdHZZ9h
9 | 83OO2iKdk1Oco+7qc7MFaItoQsempiQPniQa+uMCAwEAATANBgkqhkiG9w0BAQUF
10 | AAOBgQBxUQtSeudvSUFNZSR7QdW3Kh8Gb1+ay9LNnQ/rcW+5pXk88inHIIzIdjo9
11 | NUwhRNLRyQUzW7sHTOut5lEZpkkOTFopoa2lmwyw7pZqDoVm71aKmxoCK5nwC8t7
12 | O4cHK2mWeZ1moUuemdKQZFVMAGS8TBgTlCump311o/2qOzEZaw==
13 | -----END CERTIFICATE-----
14 |
--------------------------------------------------------------------------------
/src/test/resources/server.key:
--------------------------------------------------------------------------------
1 | -----BEGIN RSA PRIVATE KEY-----
2 | MIICXQIBAAKBgQCz1qh6p9YgqMxD6GCA5yW7r/N+06u+gJxnwdigTkbZg5C69PbM
3 | hxMNHkQdwy6GWQX/lJW1rhtoboRl079YTewlxWMnrj/mAEBcA7PD5/+k2g/IQacX
4 | Okm6Ap6bLRae10dln2Hzc47aIp2TU5yj7upzswVoi2hCx6amJA+eJBr64wIDAQAB
5 | AoGALzCboxvZb1Z7yzH16L0+xIJGJbiLb4C2Ce/u1RnVM4x3dOeEv2SOVjnj699k
6 | nPJNRaSKqFLYdE3TxhiLNDO2TD5fhCHdwN+bczNLX7FH2LRGgVNi7WNGLcFOKXkp
7 | WPke9zxcqTT6QiCw9upa2VrzzMFK7mb1pYPaGDOktdraWBkCQQDa1KSQ5n3OL6ue
8 | xHS4Nl+AJhu0dtbaHD4/lKZMINbH5x/yZ8Jl0YI16cWf0ERfSqIjCWLybYaWp23D
9 | y36YHkh1AkEA0mKHzFMg/StWojLGOQmYS8SGEm6g5USOiovq2v5LYVN+kPpJj9qf
10 | ju6cPsfOuFnXpknw/x0dji0dKvHTAgSK9wJBAIwmRiN7SzVjeIHdhnd4c1+KiJHi
11 | zqWwEvn7hSoamhQ7ZU2FwI4fSUqoJua8px10mjTgTRvAo8MXBgiw6qoYMwUCQQC1
12 | hbIpx6f1CMmtFSYW3IJ9DUmo6a8FYkuimuq+nR6pEQNpT6rc5gM5rgM93+QrB8mb
13 | frzjQVnY7G/4N8KaQRUtAkAaJnEV2MFXgKdiE8uLuGnrRBjRovDxM93H3zjlTAaO
14 | fSkL6WL8/g2RYrw2/W4WNu8I9Eqh0XlqSelFQYLd5FQE
15 | -----END RSA PRIVATE KEY-----
16 |
--------------------------------------------------------------------------------
/src/test/resources/stunnel.conf:
--------------------------------------------------------------------------------
1 | client=no
2 | foreground=yes
3 | debug=7
4 | pid=/tmp/stunnel.pid
5 | cert=src/test/resources/server.crt
6 | key=src/test/resources/server.key
7 | [smpp]
8 | accept=2777
9 | connect=127.0.0.1:2776
10 |
--------------------------------------------------------------------------------