Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

COctetString update #33

Open
wants to merge 18 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,16 @@ syntax:glob
.gwt/
.project
.classpath
.externalToolBuilders

# IntelliJ Project Files
*.iml
*.ipr
*.iws
.idea/

# MAC_OSX
*.DS_Store

version.properties
git.properties
4 changes: 4 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
language: java
jdk:
- oraclejdk7
- openjdk6
5 changes: 5 additions & 0 deletions jsmpp/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,11 @@
</licenses>

<dependencies>
<dependency>
<groupId>joda-time</groupId>
<artifactId>joda-time</artifactId>
</dependency>

<dependency>
<groupId>org.testng</groupId>
<artifactId>testng</artifactId>
Expand Down
9 changes: 5 additions & 4 deletions jsmpp/src/main/java/org/jsmpp/DefaultPDUReader.java
Original file line number Diff line number Diff line change
Expand Up @@ -40,12 +40,13 @@ public Command readPDUHeader(DataInputStream in)
header.setCommandLength(in.readInt());

if (header.getCommandLength() < 16) {
// command length to short, read the left dump anyway
// command length too short, read the left dump anyway
byte[] dump = new byte[header.getCommandLength()];
in.read(dump, 4, header.getCommandLength() - 4);

if (header.getCommandLength() >= 4) {
in.read(dump, 4, header.getCommandLength() - 4);
}
throw new InvalidCommandLengthException("Command length "
+ header.getCommandLength() + " is to short");
+ header.getCommandLength() + " is too short");
}
header.setCommandId(in.readInt());
header.setCommandStatus(in.readInt());
Expand Down
2 changes: 1 addition & 1 deletion jsmpp/src/main/java/org/jsmpp/PDUReader.java
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ public interface PDUReader {
*
* @param in is the input stream of the pdu.
* @return the header of smpp command.
* @throws InvalidCommandLengthException if command_length is to short.
* @throws InvalidCommandLengthException if command_length is too short.
* @throws IOException if an I/O error occurs.
*/
public Command readPDUHeader(DataInputStream in)
Expand Down
44 changes: 28 additions & 16 deletions jsmpp/src/main/java/org/jsmpp/bean/OptionalParameter.java
Original file line number Diff line number Diff line change
Expand Up @@ -256,23 +256,32 @@ protected byte[] serializeValue() {
public static class COctetString extends OctetString {

public COctetString(short tag, String value, String charsetName)
throws UnsupportedEncodingException {
super(tag, value, charsetName);
}
throws UnsupportedEncodingException {
super(tag, new byte[value.getBytes(charsetName).length + 1]);
byte[] bytes = value.getBytes(charsetName);
System.arraycopy(bytes, 0, this.value, 0, bytes.length);
this.value[bytes.length] = (byte) 0x00;
}

public COctetString(short tag, String value) {
super(tag, new byte[value.getBytes().length + 1]);
byte[] bytes = value.getBytes();
System.arraycopy(bytes, 0, this.value, 0, bytes.length);
this.value[bytes.length] = (byte) 0x00;
return;
}

public COctetString(short tag, byte[] value) {
super(tag, value);
}

@Override
public String getValueAsString() {
byte[] s = new byte[(value.length > 0 ? value.length - 1 : 0)];
System.arraycopy(value, 0, s, 0, s.length);
return new String(s);
}

public COctetString(short tag, String value) {
super(tag, value);
}

public COctetString(short tag, byte[] value) {
super(tag, value);
}

@Override
public String getValueAsString() {
return new String(getValue());
}

}

/**
Expand Down Expand Up @@ -2150,6 +2159,9 @@ private Vendor_specific_msc_addr(short tag, byte value[]) {
super(tag, value);
try {
address = new String(value, 2, value.length-2, "ISO-8859-1");
} catch (StringIndexOutOfBoundsException e) {
// TODO: do something better
e.printStackTrace();
} catch (UnsupportedEncodingException e) {
// TODO: do something better
e.printStackTrace();
Expand Down
4 changes: 4 additions & 0 deletions jsmpp/src/main/java/org/jsmpp/session/SMPPServerSession.java
Original file line number Diff line number Diff line change
Expand Up @@ -536,7 +536,11 @@ private void readPDU() {
} catch (SocketTimeoutException e) {
notifyNoActivity();
} catch (IOException e) {
logger.warn("IOException while reading: {}", e.getMessage());
close();
} catch (RuntimeException e) {
logger.warn("RuntimeException: {}", e.getMessage());
unbindAndClose();
}
}

Expand Down
19 changes: 11 additions & 8 deletions jsmpp/src/main/java/org/jsmpp/session/SMPPSession.java
Original file line number Diff line number Diff line change
Expand Up @@ -218,23 +218,23 @@ public String connectAndBind(String host, int port,
if (sequence().currentValue() != 1) {
throw new IOException("Failed connecting");
}

conn = connFactory.createConnection(host, port);
logger.info("Connected");

conn.setSoTimeout(getEnquireLinkTimer());

sessionContext.open();
try {
in = new DataInputStream(conn.getInputStream());
out = conn.getOutputStream();

pduReaderWorker = new PDUReaderWorker();
pduReaderWorker.start();
String smscSystemId = sendBind(bindParam.getBindType(), bindParam.getSystemId(), bindParam.getPassword(), bindParam.getSystemType(),
bindParam.getInterfaceVersion(), bindParam.getAddrTon(), bindParam.getAddrNpi(), bindParam.getAddressRange(), timeout);
sessionContext.bound(bindParam.getBindType());

enquireLinkSender = new EnquireLinkSender();
enquireLinkSender.start();
return smscSystemId;
Expand Down Expand Up @@ -636,9 +636,12 @@ private void readPDU() {
} catch (SocketTimeoutException e) {
notifyNoActivity();
} catch (IOException e) {
logger.warn("IOException while reading: {}", e.getMessage());
close();
}
logger.warn("IOException while reading: {}", e.getMessage());
close();
} catch (RuntimeException e) {
logger.warn("RuntimeException: {}", e.getMessage());
unbindAndClose();
}
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ public String format(Calendar calendar) {
if (calendar == null) {
return null;
}
int year = calendar.get(Calendar.YEAR) - 2000;
int year = calendar.get(Calendar.YEAR) % 100;
int month = calendar.get(Calendar.MONTH) + 1;
int day = calendar.get(Calendar.DAY_OF_MONTH);
int hour = calendar.get(Calendar.HOUR_OF_DAY);
Expand Down
96 changes: 56 additions & 40 deletions jsmpp/src/main/java/org/jsmpp/util/RelativeTimeFormatter.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,59 +20,74 @@
import java.util.TimeZone;

/**
* Relative time formatter is {@link TimeFormatter} implementation referred to
* SMPP Protocol Specification v3.4 point 7.1.1.
*
* @author uudashr
* Relative time formatter is {@link TimeFormatter} implementation referred to SMPP Protocol Specification v3.4 point
* 7.1.1.
*
* @author pmoerenhout
*/
public class RelativeTimeFormatter implements TimeFormatter {
private final TimeZone timezone;


private static TimeZone utcTimeZone = TimeZone.getTimeZone("UTC");

/**
* Time/Date ASCII format for Absolute Time Format is:
*
* YYMMDDhhmmsstnnp (refer for SMPP Protocol Specification v3.4)
* Time/Date ASCII format for Relative Time Format is:
*
* YYMMDDhhmmss000R (refer for SMPP Protocol Specification v3.4)
*/
private static final String DATE_FORMAT = "{0,number,00}{1,number,00}{2,number,00}{3,number,00}{4,number,00}{5,number,00}000R";

/**
* Construct with default timezone.
* Construct
*/
public RelativeTimeFormatter() {
this(TimeZone.getDefault());
}

/**
* Construct with specified SMSC timezone.
*
* @param timezone is the SMSC timezone.
* Return the relative time against current (SMSC) datetime.
*
* @param calendar the datetime.
* @return The relative time between the calendar date and the SMSC calendar date.
*/
public RelativeTimeFormatter(TimeZone timezone) {
this.timezone = timezone;
}

public String format(Calendar calendar) {
if (calendar == null) {
// As the relative period is calculated on epoch (timeInMillis), no TimeZone information is needed
Calendar smscCalendar = Calendar.getInstance();
return format(calendar, smscCalendar);
}

/**
* Return the relative time from the calendar datetime against the SMSC datetime.
*
* @param calendar the date.
* @param smscCalendar the SMSC date.
* @return The relative time between the calendar date and the SMSC calendar date.
*/
public String format(Calendar calendar, Calendar smscCalendar) {
if (calendar == null || smscCalendar == null) {
return null;
}

long relativeTime = calendar.getTimeInMillis()
- calendar.getTimeZone().getOffset(calendar.getTimeInMillis())
+ timezone.getOffset(calendar.getTimeInMillis());

Calendar cal = Calendar.getInstance();
cal.setTimeInMillis(relativeTime);
int year = cal.get(Calendar.YEAR) - 2000;
int month = cal.get(Calendar.MONTH) + 1;
int day = cal.get(Calendar.DAY_OF_MONTH);
int hour = cal.get(Calendar.HOUR_OF_DAY);
int minute = cal.get(Calendar.MINUTE);
int second = cal.get(Calendar.SECOND);

return format(year, month, day, hour, minute, second);

long diffTimeInMillis = calendar.getTimeInMillis() - smscCalendar.getTimeInMillis();
if (diffTimeInMillis < 0) {
throw new IllegalArgumentException("The requested relative time has already past.");
}

// calculate period from epoch, this is not as accurate as Joda-Time Period class or Java 8 Period
Calendar offsetEpoch = Calendar.getInstance(utcTimeZone);
offsetEpoch.setTimeInMillis(diffTimeInMillis);
int years = offsetEpoch.get(Calendar.YEAR) - 1970;
int months = offsetEpoch.get(Calendar.MONTH);
int days = offsetEpoch.get(Calendar.DAY_OF_MONTH) - 1;
int hours = offsetEpoch.get(Calendar.HOUR_OF_DAY);
int minutes = offsetEpoch.get(Calendar.MINUTE);
int seconds = offsetEpoch.get(Calendar.SECOND);

if (years >= 100) {
throw new IllegalArgumentException("The requested relative time is more then a century (" + years + " years).");
}

return format(years, months, days, hours, minutes, seconds);
}

public String format(Date date) {
if (date == null) {
return null;
Expand All @@ -81,10 +96,11 @@ public String format(Date date) {
cal.setTime(date);
return format(cal);
}

public static final String format(Integer year, Integer month,
Integer day, Integer hour, Integer minute, Integer second) {
Object[] args = new Object[] {year, month, day, hour, minute, second};
Integer day, Integer hour, Integer minute, Integer second) {
Object[] args = new Object[]{ year, month, day, hour, minute, second };
return MessageFormat.format(DATE_FORMAT, args);
}

}
76 changes: 76 additions & 0 deletions jsmpp/src/test/java/org/jsmpp/DefaultPDUReaderTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
package org.jsmpp;

import static org.testng.Assert.assertEquals;

import java.io.ByteArrayInputStream;
import java.io.DataInputStream;

import org.jsmpp.bean.Command;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;

public class DefaultPDUReaderTest {

DefaultPDUReader defaultPDUReader;

@BeforeMethod
public void setUp() throws Exception {
defaultPDUReader = new DefaultPDUReader();
}

@Test
public void testPDUHeader() throws Exception {

DataInputStream in = new DataInputStream(
new ByteArrayInputStream(
new byte[]{ 0x00, 0x00, 0x00, 0x10, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c }));

Command command = defaultPDUReader.readPDUHeader(in);

assertEquals(command.getCommandLength(), 16, "Command length differs");
assertEquals(command.getCommandId(), 0x01020304, "Command id differs");
assertEquals(command.getCommandStatus(), 0x05060708, "Command status differs");
assertEquals(command.getSequenceNumber(), 0x090a0b0c, "Sequence number differs");
}

@Test(groups = "checkintest", expectedExceptions = InvalidCommandLengthException.class)
public void testInvalidPDUHeaderWithCommandLengthZero() throws Exception {

DataInputStream in = new DataInputStream(
new ByteArrayInputStream(
new byte[]{ 0x00, 0x00, 0x00, 0x00 }));
defaultPDUReader.readPDUHeader(in);
}

@Test(groups = "checkintest", expectedExceptions = InvalidCommandLengthException.class)
public void testInvalidPDUHeaderWithCommandLengthFour() throws Exception {

DataInputStream in = new DataInputStream(
new ByteArrayInputStream(
new byte[]{ 0x00, 0x00, 0x00, 0x04 }));

defaultPDUReader.readPDUHeader(in);
}

@Test(groups = "checkintest", expectedExceptions = InvalidCommandLengthException.class)
public void testInvalidPDUHeaderWithCommandLengthEigth() throws Exception {

DefaultPDUReader defaultPDUReader = new DefaultPDUReader();

DataInputStream in = new DataInputStream(
new ByteArrayInputStream(
new byte[]{ 0x00, 0x00, 0x00, 0x08, 0x01, 0x02, 0x03, 0x04 }));
defaultPDUReader.readPDUHeader(in);
}

@Test(groups = "checkintest", expectedExceptions = InvalidCommandLengthException.class)
public void testInvalidPDUHeaderWithCommandLengthFifteen() throws Exception {

DefaultPDUReader defaultPDUReader = new DefaultPDUReader();

DataInputStream in = new DataInputStream(
new ByteArrayInputStream(
new byte[]{ 0x00, 0x00, 0x00, 0x0f, 0x01, 0x02, 0x03, 0x04, 0x00, 0x00, 0x00, 0x00, 0x40, 0x41, 0x42, 0x43 }));
defaultPDUReader.readPDUHeader(in);
}
}
Loading