RandomReferenceNumberGenerator.java
package fr.sii.ogham.sms.splitter;
import java.util.Random;
/**
* In the cellular phone industry, mobile phones and their networks sometimes
* support concatenated short message service (or concatenated SMS) to overcome
* the limitation on the number of characters that can be sent in a single SMS
* text message transmission (which is usually 160). Using this method, long
* messages are split into smaller messages by the sending device and recombined
* at the receiving end. Each message is then billed separately. When the
* feature works properly, it is nearly transparent to the user, appearing as a
* single long text message.
*
* <p>
* One way of sending concatenated SMS (CSMS) is to split the message into 153
* 7-bit character parts (134 octets), and sending each part with a User Data
* Header (UDH) tacked onto the beginning. A UDH can be used for various
* purposes and its contents and size varies accordingly, but a UDH for
* concatenating SMSes look like this:
*
* <ul>
* <li>Field 1 (1 octet): Length of User Data Header, in this case 05.</li>
* <li>Field 2 (1 octet): Information Element Identifier, equal to 00
* (Concatenated short messages, 8-bit reference number)</li>
* <li>Field 3 (1 octet): Length of the header, excluding the first two fields;
* equal to 03</li>
* <li>Field 4 (1 octet): 00-FF, CSMS reference number, must be same for all the
* SMS parts in the CSMS</li>
* <li>Field 5 (1 octet): 00-FF, total number of parts. The value shall remain
* constant for every short message which makes up the concatenated short
* message. If the value is zero then the receiving entity shall ignore the
* whole information element</li>
* <li>Field 6 (1 octet): 00-FF, this part's number in the sequence. The value
* shall start at 1 and increment for every short message which makes up the
* concatenated short message. If the value is zero or greater than the value in
* Field 5 then the receiving entity shall ignore the whole information element.
* [ETSI Specification: GSM 03.40 Version 5.3.0: July 1996]</li>
* </ul>
*
* <p>
* It is possible to use a 16 bit CSMS reference number in order to reduce the
* probability that two different concatenated messages are sent with identical
* reference numbers to a receiver. In this case, the User Data Header shall be:
*
* <ul>
* <li>Field 1 (1 octet): Length of User Data Header (UDL), in this case
* 06.</li>
* <li>Field 2 (1 octet): Information Element Identifier, equal to 08
* (Concatenated short messages, 16-bit reference number)</li>
* <li>Field 3 (1 octet): Length of the header, excluding the first two fields;
* equal to 04</li>
* <li>Field 4 (2 octets): 0000-FFFF, CSMS reference number, must be same for
* all the SMS parts in the CSMS</li>
* <li>Field 5 (1 octet): 00-FF, total number of parts. The value shall remain
* constant for every short message which makes up the concatenated short
* message. If the value is zero then the receiving entity shall ignore the
* whole information element</li>
* <li>Field 6 (1 octet): 00-FF, this part's number in the sequence. The value
* shall start at 1 and increment for every short message which makes up the
* concatenated short message. If the value is zero or greater than the value in
* Field 5 then the receiving entity shall ignore the whole information element.
* [ETSI Specification: GSM 03.40 Version 5.3.0: July 1996]</li>
* </ul>
*
* <p>
* This implementation generates a value using {@link Random} utility.
*
* @author Aurélien Baudet
*
*/
public class RandomReferenceNumberGenerator implements ReferenceNumberGenerator {
private final Random random;
private final int length;
/**
* Uses a default {@link Random} to generate random reference numbers. The
* generated reference is only one octet length.
*
* <p>
* If you want a custom number generation, use
* {@link #RandomReferenceNumberGenerator(Random)}.
*/
@SuppressWarnings("squid:S2245")
public RandomReferenceNumberGenerator() {
this(new Random());
}
/**
* Use the provided {@link Random} to generate random reference numbers. The
* generated reference is only one octet length.
*
* <p>
* If you want to generate a reference number of two octets, use
* {@link #RandomReferenceNumberGenerator(Random, int)}.
*
* @param random
* used to generate random numbers
*/
public RandomReferenceNumberGenerator(Random random) {
this(random, 1);
}
/**
* Use the provided {@link Random} to generate random reference number byte
* arrays. Each reference number byte array has a size of {@code length}
* parameter.
*
* @param random
* used to generate random numbers
* @param length
* the number of octets for each reference number
*/
public RandomReferenceNumberGenerator(Random random, int length) {
super();
this.random = random;
this.length = length;
}
@Override
public byte[] generateReferenceNumber() {
byte[] referenceNumber = new byte[length];
random.nextBytes(referenceNumber);
return referenceNumber;
}
}