Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
package com.cloudhopper.commons.gsm;
/*
* #%L
* ch-commons-gsm
* %%
* Copyright (C) 2012 Cloudhopper by Twitter
* %%
* Licensed 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.
* #L%
*/
import com.cloudhopper.commons.util.HexUtil;
/**
* A class that represents an immutable data coding scheme. This class makes it
* easier to work with a Data Coding Scheme specifications in ETSI GSM 3.38.
*
* Bit 7 6 5 4 3 2 1 0
*
* Bits 7..4 contain the "Coding Group Bits" which control what values
* are contained in bits 3..0 OR even 5..0
*
* 0000: Character Encoding Group
*
*
Bits 0,1,2,3 Represent 16 Language Encodings
*
*
* 00xx: General Data Coding Group
*
*
If Bits 4 & 5 are 0 & 0 then see above "0000 Character Encoding Group"
*
Message Class (Bit 0 & 1) (default 0, 0)
*
Alphabet (Bit 2 & 3) (default 0, 0)
*
Message Class Present (Bit 4) (whether bits 0 & 1 have meaning)
*
Compression Flag (Bit 5) (0 - uncompressed, 1 - compressed)
Bit 3 (0 - Set Indication Inactive, 1 - Set Indication Active)
*
*
* 1111: Message Class Group
*
*
Message Class (Bit 0 & 1)
*
Alphabet (Bit 2 & 3) (Default, 8 Bit, USC2)
*
*
* @author joelauer
*/
public class DataCoding {
public enum Group {
/** Character encoding group (default). Basically, represents the
16 language encodings possible. */
CHARACTER_ENCODING,
/** General data coding group. Represents a message class, a couple
different character sets, and compression true/false. */
GENERAL,
/** A message waiting indicator was set along with just two possible
* languages. Either DEFAULT or UCS2. */
MESSAGE_WAITING_INDICATION,
/** A message class was set along with 3 possible languages. */
MESSAGE_CLASS,
/** Represents a reserved data coding scheme was used and likely was
* something custom. */
RESERVED
}
// message class constants
public static final byte MESSAGE_CLASS_0 = 0;
public static final byte MESSAGE_CLASS_1 = 1;
public static final byte MESSAGE_CLASS_2 = 2;
public static final byte MESSAGE_CLASS_3 = 3;
// character encoding constants
/** SMSC Default Alphabet (default) */
public static final byte CHAR_ENC_DEFAULT = 0x00;
/** IA5 (CCITT T.50)/ASCII (ANSI X3.4) */
public static final byte CHAR_ENC_IA5 = 0x01;
/** Octet unspecified (8-bit binary) defined for TDMA and/ or CDMA but not defined for GSM */
public static final byte CHAR_ENC_8BITA = 0x02;
/** Latin 1 (ISO-8859-1) */
public static final byte CHAR_ENC_LATIN1 = 0x03;
/** Octet unspecified (8-bit binary) ALL TECHNOLOGIES */
public static final byte CHAR_ENC_8BIT = 0x04;
/** JIS (X 0208-1990) */
public static final byte CHAR_ENC_JIS = 0x05;
/** Cyrllic (ISO-8859-5) */
public static final byte CHAR_ENC_CYRLLIC = 0x06;
/** Latin/Hebrew (ISO-8859-8) */
public static final byte CHAR_ENC_HEBREW = 0x07;
/** UCS2 (ISO/IEC-10646) */
public static final byte CHAR_ENC_UCS2 = 0x08;
/** Pictogram Encoding */
public static final byte CHAR_ENC_PICTO = 0x09;
/** ISO-2022-JP (Music Codes) */
public static final byte CHAR_ENC_MUSIC = 0x0A;
/** Reserved: 0x0B */
public static final byte CHAR_ENC_RSRVD = 0x0B;
/** Reserved: 0x0C */
public static final byte CHAR_ENC_RSRVD2 = 0x0C;
/** Extended Kanji JIS(X 0212-1990) */
public static final byte CHAR_ENC_EXKANJI = 0x0D;
/** KS C 5601 */
public static final byte CHAR_ENC_KSC5601 = 0x0E;
/** Reserved: 0x0F */
public static final byte CHAR_ENC_RSRVD3 = 0x0F;
/** NOT SUPPORTED YET
// message waiting indication store/discard constants
public static final byte MESSAGE_WAITING_COMMAND_DISCARD = 0;
public static final byte MESSAGE_WAITING_COMMAND_STORE = 1;
// message waiting indicator constants
public static final byte MESSAGE_WAITING_IND_INACTIVE = 0;
public static final byte MESSAGE_WAITING_IND_ACTIVE = 1;
// message waiting indication type constants
public static final byte MESSAGE_WAITING_TYPE_VOICEMAIL = 0;
public static final byte MESSAGE_WAITING_TYPE_FAX = 1;
public static final byte MESSAGE_WAITING_TYPE_EMAIL = 2;
public static final byte MESSAGE_WAITING_TYPE_OTHER = 3;
*/
// actual byte value
private final byte dcs;
// "group" this value falls under
private final Group codingGroup;
private final byte characterEncoding;
private final byte messageClass;
private final boolean compressed;
// NOTE: leave out message waiting stuff for now...
protected DataCoding(byte dcs, Group codingGroup, byte characterEncoding, byte messageClass, boolean compressed) {
this.dcs = dcs;
this.codingGroup = codingGroup;
this.characterEncoding = characterEncoding;
this.messageClass = messageClass;
this.compressed = compressed;
}
public byte getByteValue() {
return this.dcs;
}
public Group getCodingGroup() {
return this.codingGroup;
}
public byte getCharacterEncoding() {
return this.characterEncoding;
}
public byte getMessageClass() {
return this.messageClass;
}
public boolean isCompressed() {
return this.compressed;
}
/**
* Creates a "Character Encoding" group data coding scheme where 16 different
* languages are supported. This method validates the range and
* sets the message class to 0 and compression flags to false.
* @param characterEncoding The different possible character encodings
* @return A new immutable DataCoding instance representing this data coding scheme
* @throws IllegalArgumentException Thrown if the range is not supported.
*/
static public DataCoding createCharacterEncodingGroup(byte characterEncoding) throws IllegalArgumentException {
// bits 3 thru 0 of the encoding represent 16 languages
// make sure the top bits 7 thru 4 are not set
if ((characterEncoding & 0xF0) != 0) {
throw new IllegalArgumentException("Invalid characterEncoding [0x" + HexUtil.toHexString(characterEncoding) + "] value used: only 16 possible for char encoding group");
}
return new DataCoding(characterEncoding, Group.CHARACTER_ENCODING, characterEncoding, MESSAGE_CLASS_0, false);
}
/**
* Creates a "Message Class" group data coding scheme where 2 different
* languages are supported (8BIT or DEFAULT). This method validates the
* message class.
* @param characterEncoding Either CHAR_ENC_DEFAULT or CHAR_ENC_8BIT
* @param messageClass The 4 different possible message classes (0-3)
* @return A new immutable DataCoding instance representing this data coding scheme
* @throws IllegalArgumentException Thrown if the range is not supported.
*/
static public DataCoding createMessageClassGroup(byte characterEncoding, byte messageClass) throws IllegalArgumentException {
// only default or 8bit are valid
if (!(characterEncoding == CHAR_ENC_DEFAULT || characterEncoding == CHAR_ENC_8BIT)) {
throw new IllegalArgumentException("Invalid characterEncoding [0x" + HexUtil.toHexString(characterEncoding) + "] value used: only default or 8bit supported for message class group");
}
// validate the message class
if (messageClass < 0 || messageClass > 3) {
throw new IllegalArgumentException("Invalid messageClass [0x" + HexUtil.toHexString(messageClass) + "] value used: 0x00-0x03 only valid range");
}
// need to build this dcs value (top 4 bits are 1, start with 0xF0)
byte dcs = (byte)0xF0;
// 8bit encoding means bit 2 goes on
if (characterEncoding == CHAR_ENC_8BIT) {
dcs |= (byte)0x04;
}
// merge in the message class (bottom 2 bits)
dcs |= messageClass;
return new DataCoding(dcs, Group.MESSAGE_CLASS, characterEncoding, messageClass, false);
}
/**
* Creates a "General" group data coding scheme where 3 different
* languages are supported (8BIT, UCS2, or DEFAULT). This method validates the
* message class.
* @param characterEncoding Either CHAR_ENC_DEFAULT, CHAR_ENC_8BIT, or CHAR_ENC_UCS2
* @param messageClass The 4 different possible message classes (0-3). If null,
* the "message class" not active flag will not be set.
* @param compressed If true, the message is compressed. False if unpacked.
* @return A new immutable DataCoding instance representing this data coding scheme
* @throws IllegalArgumentException Thrown if the range is not supported.
*/
static public DataCoding createGeneralGroup(byte characterEncoding, Byte messageClass, boolean compressed) throws IllegalArgumentException {
// only default, 8bit, or UCS2 are valid
if (!(characterEncoding == CHAR_ENC_DEFAULT || characterEncoding == CHAR_ENC_8BIT || characterEncoding == CHAR_ENC_UCS2)) {
throw new IllegalArgumentException("Invalid characterEncoding [0x" + HexUtil.toHexString(characterEncoding) + "] value used: only default, 8bit, or UCS2 supported for general group");
}
// validate the message class (only if non-null)
if (messageClass != null && (messageClass.byteValue() < 0 || messageClass.byteValue() > 3)) {
throw new IllegalArgumentException("Invalid messageClass [0x" + HexUtil.toHexString(messageClass) + "] value used: 0x00-0x03 only valid range");
}
// need to build this dcs value (top 2 bits are 0, start with 0x00)
byte dcs = 0;
if (compressed) {
dcs |= (byte)0x20; // turn bit 5 on
}
// if a message class is present turn bit 4 on
if (messageClass != null) {
dcs |= (byte)0x10; // turn bit 4 on
// bits 1 thru 0 is the message class
// merge in the message class (bottom 2 bits)
dcs |= messageClass;
}
// merge in language encodings (they nicely merge in since only default, 8-bit or UCS2)
dcs |= characterEncoding;
return new DataCoding(dcs, Group.GENERAL, characterEncoding, (messageClass == null ? MESSAGE_CLASS_0 : messageClass.byteValue()), compressed);
}
static public DataCoding createMessageWaitingIndicationGroup(byte characterEncoding, boolean store, boolean active, byte indicatorType) throws IllegalArgumentException {
// only default or UCS2 are valid
if (!(characterEncoding == CHAR_ENC_DEFAULT || characterEncoding == CHAR_ENC_UCS2)) {
throw new IllegalArgumentException("Invalid characterEncoding [0x" + HexUtil.toHexString(characterEncoding) + "] value used: only default or UCS2 supported for MWI group");
}
// validate the indicatorType
if (indicatorType < 0 || indicatorType > 3) {
throw new IllegalArgumentException("Invalid indicatorType [0x" + HexUtil.toHexString(indicatorType) + "] value used: 0x00-0x03 only valid range");
}
// need to build this dcs value (top 2 bits are 1, start with 0xC0)
byte dcs = (byte)0xC0;
// bit 5: 0=default, 1=UCS2
if (characterEncoding == CHAR_ENC_UCS2) {
dcs |= (byte)0x20;
}
// bit 4: 0=discard, 1=store
if (store) {
dcs |= (byte)0x10;
}
// bit 3: indicator active
if (active) {
dcs |= (byte)0x08;
}
// bit 2: means nothing
// bit 1 thru 0 is the type of indicator
dcs |= indicatorType;
return new DataCoding(dcs, Group.MESSAGE_WAITING_INDICATION, characterEncoding, MESSAGE_CLASS_0, false);
}
/**
* Creates a "Reserved" group data coding scheme. NOTE: this method does
* not actually check if the byte value is reserved, its assumed the caller
* just wants to store the byte value.
* @param dcs The data coding scheme byte value
* @return A new immutable DataCoding instance representing this data coding scheme
*/
static public DataCoding createReservedGroup(byte dcs) {
return new DataCoding(dcs, Group.RESERVED, CHAR_ENC_DEFAULT, MESSAGE_CLASS_0, false);
}
/**
* Parse the data coding scheme value into something usable and makes various
* values easy to use. If a "reserved" value is used, returns a data coding
* representing the same byte value, but all properties to their defaults.
* @param dcs The byte value of the data coding scheme
* @return A new immutable DataCoding instance representing this data coding scheme
*/
static public DataCoding parse(byte dcs) {
try {
// if bits 7 thru 4 are all off, this represents a simple character encoding group
if ((dcs & (byte)0xF0) == 0x00) {
// the raw dcs value is exactly our 16 possible languaged
return createCharacterEncodingGroup(dcs);
// if bits 7 thru 4 are all on, this represents a message class group
} else if ((dcs & (byte)0xF0) == (byte)0xF0) {
// bit 2 is the language encoding
byte characterEncoding = CHAR_ENC_DEFAULT;
if ((dcs & (byte)0x04) == (byte)0x04) {
characterEncoding = CHAR_ENC_8BIT;
}
// bits 1 thru 0 is the message class
byte messageClass = (byte)(dcs & (byte)0x03);
return createMessageClassGroup(characterEncoding, messageClass);
// at this point if bits 7 and 6 are off, then general data coding group
} else if ((dcs & (byte)0xC0) == (byte)0x00) {
// bit 5 represents "compression"
boolean compressed = false;
if ((dcs & (byte)0x20) == (byte)0x20) {
compressed = true;
}
// bits 1 thru 0 is the message class
byte tempMessageClass = (byte)(dcs & (byte)0x03);
Byte messageClass = null;
// bit 4 on means the message class becomes used
if ((dcs & (byte)0x10) == (byte)0x10) {
messageClass = new Byte(tempMessageClass);
}
// bits 3 and 2 represent the language encodings (nicely match default, 8-bit, or UCS2)
byte characterEncoding = (byte)(dcs & (byte)0x0C);
return createGeneralGroup(characterEncoding, messageClass, compressed);
// at this point if bits 7 and 6 are on, then bits 5 and 4 determine MWI
} else if ((dcs & (byte)0xC0) == (byte)0xC0) {
// bit 5: 0=default, 1=UCS2
byte characterEncoding = CHAR_ENC_DEFAULT;
if ((byte)(dcs & (byte)0x20) == 0x20) {
characterEncoding = CHAR_ENC_UCS2;
}
// bit 4: 0=discard, 1=store
boolean store = false;
if ((byte)(dcs & (byte)0x10) == 0x10) {
store = true;
}
// bit 3: indicator active
boolean indicatorActive = false;
if ((byte)(dcs & (byte)0x08) == 0x08) {
indicatorActive = true;
}
// bit 2: means nothing
// bit 1 thru 0 is the type of indicator
byte indicatorType = (byte)(dcs & (byte)0x03);
return createMessageWaitingIndicationGroup(characterEncoding, store, indicatorActive, indicatorType);
} else {
return createReservedGroup(dcs);
}
} catch (IllegalArgumentException e) {
return createReservedGroup(dcs);
}
}
}