class GsmUtil {

    static public byte[][] createConcatenatedBinaryShortMessages(byte[] binaryShortMessage, byte referenceNum) throws IllegalArgumentException {
        if (binaryShortMessage == null) {
            return null;
        }
        // if the short message does not need to be concatenated
        if (binaryShortMessage.length <= 140) {
            return null;
        }

        // since the UDH will be 6 bytes, we'll split the data into chunks of 134
        int numParts = (int) (binaryShortMessage.length / 134) + (binaryShortMessage.length % 134 != 0 ? 1 : 0);
        //logger.debug("numParts=" + numParts);

        byte[][] shortMessageParts = new byte[numParts][];

        for (int i = 0; i < numParts; i++) {
            // default this part length to max of 134
            int shortMessagePartLength = 134;
            if ((i + 1) == numParts) {
                // last part (only need to add remainder)
                shortMessagePartLength = binaryShortMessage.length - (i * 134);
            }

            //logger.debug("part " + i + " len: " + shortMessagePartLength);

            // part will be UDH (6 bytes) + length of part
            byte[] shortMessagePart = new byte[6 + shortMessagePartLength];
            // Field 1 (1 octet): Length of User Data Header, in this case 05.
            shortMessagePart[0] = (byte) 0x05;
            // Field 2 (1 octet): Information Element Identifier, equal to 00 (Concatenated short messages, 8-bit reference number)
            shortMessagePart[1] = (byte) 0x00;
            // Field 3 (1 octet): Length of the header, excluding the first two fields; equal to 03
            shortMessagePart[2] = (byte) 0x03;
            // Field 4 (1 octet): 00-FF, CSMS reference number, must be same for all the SMS parts in the CSMS
            shortMessagePart[3] = referenceNum;
            // 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
            shortMessagePart[4] = (byte) numParts;
            // 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]
            shortMessagePart[5] = (byte) (i + 1);

            // copy this part's user data onto the end
            System.arraycopy(binaryShortMessage, (i * 134), shortMessagePart, 6, shortMessagePartLength);
            shortMessageParts[i] = shortMessagePart;
        }

        return shortMessageParts;
    }

}