/**
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.camel.component.smpp;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Splitter for messages use National Language Lock Table
* <p/>
* @see 3GPP 23.038 Reference
*/
public class SmppNLSTSplitter extends SmppSplitter {
/**
* The length of the UDH for single short message in bytes.
* 0x25 - UDHIE_NLI_IDENTIFIER
* 0x01 - Length of the header
* 0xXX - Locking shift table indicator the Language
*/
protected static final int UDHIE_NLI_SINGLE_MSG_HEADER_LENGTH = 0x03; // header length for single message
/**
* The real length of the UDH for single short message
*/
protected static final int UDHIE_NLI_SINGLE_MSG_HEADER_REAL_LENGTH = UDHIE_NLI_SINGLE_MSG_HEADER_LENGTH + 1;
/**
* The length of the UDH for splitted short messages, in bytes.
* 0x08 Overall header length
* 0x00 The value that identifier length of the SAR fragment. (8bit reference number only)
* 0x03 The length of the SAR fragment
* 0xXX The reference number for SAR
* 0xXX Total number of splitted / segmented messages
* 0xXX Segment number
* 0x25 National language locking shift element identifier
* 0x01 Length of the header
* 0xXX Locking shift table indicator for the Language (ie: 0x01 for Turkish)
*/
protected static final int UDHIE_NLI_MULTI_MSG_HEADER_LENGTH = 0x08;
/**
* The real length of the UDH for segmentet short messages
*/
protected static final int UDHIE_NLI_MULTI_MSG_HEADER_REAL_LENGTH = UDHIE_NLI_MULTI_MSG_HEADER_LENGTH + 1;
/**
* The element identifier value for the National Language Locking Table
*/
protected static final int UDHIE_NLI_IDENTIFIER = 0x25;
/**
* The length of the NLI header
*/
protected static final int UDHIE_NLI_HEADER_LENGTH = 0x01;
/**
* The maximum length in chars of the NLI messages.
* <p/>
* Each letter will be represented as 7 bit (like GSM8)
*/
public static final int MAX_MSG_CHAR_SIZE = (MAX_MSG_BYTE_LENGTH * 8 / 7) - (UDHIE_NLI_SINGLE_MSG_HEADER_REAL_LENGTH + 1);
public static final int MAX_SEG_BYTE_SIZE = (MAX_MSG_BYTE_LENGTH - UDHIE_NLI_MULTI_MSG_HEADER_REAL_LENGTH) * 8 / 7;
/**
* Locking shift table indicator for the Language, single byte
*/
private byte languageIdentifier;
private final Logger logger = LoggerFactory.getLogger(SmppNLSTSplitter.class);
public SmppNLSTSplitter(int currentLength, byte languageIdentifier) {
super(MAX_MSG_CHAR_SIZE, MAX_SEG_BYTE_SIZE, currentLength);
this.languageIdentifier = languageIdentifier;
}
public byte[][] split(byte[] message) {
if (!isSplitRequired()) {
byte[] nliMessage = new byte[UDHIE_NLI_SINGLE_MSG_HEADER_REAL_LENGTH + message.length];
nliMessage[0] = (byte) UDHIE_NLI_SINGLE_MSG_HEADER_LENGTH;
nliMessage[1] = (byte) UDHIE_NLI_IDENTIFIER;
nliMessage[2] = (byte) UDHIE_NLI_HEADER_LENGTH;
nliMessage[3] = this.languageIdentifier;
System.arraycopy(message, 0, nliMessage, 4, message.length);
return new byte[][]{nliMessage};
}
int segmentLength = getSegmentLength();
// determine how many messages
int segmentNum = message.length / segmentLength;
int messageLength = message.length;
if (segmentNum > MAX_SEG_COUNT) {
// this is too long, can't fit, so chop
segmentNum = MAX_SEG_COUNT;
messageLength = segmentNum * segmentLength;
}
if ((messageLength % segmentLength) > 0) {
segmentNum++;
}
byte[][] segments = new byte[segmentNum][];
int lengthOfData;
byte refNum = getReferenceNumber();
for (int i = 0; i < segmentNum; i++) {
logger.debug("segment number = {}", i);
if (segmentNum - i == 1) {
lengthOfData = messageLength - i * segmentLength;
} else {
lengthOfData = segmentLength;
}
logger.debug("Length of data = {}", lengthOfData);
segments[i] = new byte[UDHIE_NLI_MULTI_MSG_HEADER_REAL_LENGTH + lengthOfData];
logger.debug("segments[{}].length = {}", i, segments[i].length);
segments[i][0] = UDHIE_NLI_MULTI_MSG_HEADER_LENGTH; // doesn't include itself, is header length
// SAR identifier
segments[i][1] = UDHIE_IDENTIFIER_SAR;
// SAR length
segments[i][2] = UDHIE_SAR_LENGTH;
// DATAGRAM REFERENCE NUMBER
segments[i][3] = refNum;
// total number of segments
segments[i][4] = (byte) segmentNum;
// segment #
segments[i][5] = (byte) (i + 1);
// national language locking shift table, element identifier
segments[i][6] = (byte) UDHIE_NLI_IDENTIFIER;
segments[i][7] = (byte) UDHIE_NLI_HEADER_LENGTH;
segments[i][8] = this.languageIdentifier;
// now copy the data
System.arraycopy(message, i * segmentLength, segments[i], UDHIE_NLI_MULTI_MSG_HEADER_REAL_LENGTH, lengthOfData);
}
return segments;
}
}