Merge change 6338 into donut
* changes: septet-align UD after any UDH for GSM-7bit coding
This commit is contained in:
@ -455,7 +455,14 @@ public final class BearerData {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static byte[] encode7bitGsm(String msg)
|
private static int calcUdhSeptetPadding(int userDataHeaderLen) {
|
||||||
|
int udhBits = userDataHeaderLen * 8;
|
||||||
|
int udhSeptets = (udhBits + 6) / 7;
|
||||||
|
int paddingBits = (udhSeptets * 7) - udhBits;
|
||||||
|
return paddingBits;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static byte[] encode7bitGsm(String msg, int paddingBits)
|
||||||
throws CodingException
|
throws CodingException
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
@ -464,11 +471,9 @@ public final class BearerData {
|
|||||||
* an option to produce just the data without prepending
|
* an option to produce just the data without prepending
|
||||||
* the length.
|
* the length.
|
||||||
*/
|
*/
|
||||||
byte []fullData = GsmAlphabet.stringToGsm7BitPacked(msg);
|
byte []fullData = GsmAlphabet.stringToGsm7BitPacked(msg, 0, -1, paddingBits, true);
|
||||||
byte []data = new byte[fullData.length - 1];
|
byte []data = new byte[fullData.length - 1];
|
||||||
for (int i = 0; i < data.length; i++) {
|
System.arraycopy(fullData, 1, data, 0, fullData.length - 1);
|
||||||
data[i] = fullData[i + 1];
|
|
||||||
}
|
|
||||||
return data;
|
return data;
|
||||||
} catch (com.android.internal.telephony.EncodeException ex) {
|
} catch (com.android.internal.telephony.EncodeException ex) {
|
||||||
throw new CodingException("7bit GSM encode failed: " + ex);
|
throw new CodingException("7bit GSM encode failed: " + ex);
|
||||||
@ -478,9 +483,11 @@ public final class BearerData {
|
|||||||
private static void encodeUserDataPayload(UserData uData)
|
private static void encodeUserDataPayload(UserData uData)
|
||||||
throws CodingException
|
throws CodingException
|
||||||
{
|
{
|
||||||
|
// TODO(cleanup): UDH can only occur in EMS mode, meaning
|
||||||
|
// encapsulation of GSM encoding, and so the logic here should
|
||||||
|
// be refactored to more cleanly reflect this constraint.
|
||||||
|
|
||||||
byte[] headerData = null;
|
byte[] headerData = null;
|
||||||
// TODO: if there is a header, meaning EMS mode, we probably
|
|
||||||
// also want the total UD length prior to the UDH length...
|
|
||||||
if (uData.userDataHeader != null) headerData = SmsHeader.toByteArray(uData.userDataHeader);
|
if (uData.userDataHeader != null) headerData = SmsHeader.toByteArray(uData.userDataHeader);
|
||||||
int headerDataLen = (headerData == null) ? 0 : headerData.length + 1; // + length octet
|
int headerDataLen = (headerData == null) ? 0 : headerData.length + 1; // + length octet
|
||||||
|
|
||||||
@ -502,8 +509,9 @@ public final class BearerData {
|
|||||||
uData.payloadStr = "";
|
uData.payloadStr = "";
|
||||||
}
|
}
|
||||||
if (uData.msgEncoding == UserData.ENCODING_GSM_7BIT_ALPHABET) {
|
if (uData.msgEncoding == UserData.ENCODING_GSM_7BIT_ALPHABET) {
|
||||||
payloadData = encode7bitGsm(uData.payloadStr);
|
int paddingBits = calcUdhSeptetPadding(headerDataLen);
|
||||||
codeUnitCount = (payloadData.length * 8) / 7;
|
payloadData = encode7bitGsm(uData.payloadStr, paddingBits);
|
||||||
|
codeUnitCount = ((payloadData.length + headerDataLen) * 8) / 7;
|
||||||
} else if (uData.msgEncoding == UserData.ENCODING_7BIT_ASCII) {
|
} else if (uData.msgEncoding == UserData.ENCODING_7BIT_ASCII) {
|
||||||
payloadData = encode7bitAscii(uData.payloadStr, true);
|
payloadData = encode7bitAscii(uData.payloadStr, true);
|
||||||
codeUnitCount = uData.payloadStr.length();
|
codeUnitCount = uData.payloadStr.length();
|
||||||
@ -528,8 +536,9 @@ public final class BearerData {
|
|||||||
} else {
|
} else {
|
||||||
// If there is a header, we are in EMS mode, in
|
// If there is a header, we are in EMS mode, in
|
||||||
// which case we use GSM encodings.
|
// which case we use GSM encodings.
|
||||||
payloadData = encode7bitGsm(uData.payloadStr);
|
int paddingBits = calcUdhSeptetPadding(headerDataLen);
|
||||||
codeUnitCount = (payloadData.length * 8) / 7;
|
payloadData = encode7bitGsm(uData.payloadStr, paddingBits);
|
||||||
|
codeUnitCount = ((payloadData.length + headerDataLen) * 8) / 7;
|
||||||
uData.msgEncoding = UserData.ENCODING_GSM_7BIT_ALPHABET;
|
uData.msgEncoding = UserData.ENCODING_GSM_7BIT_ALPHABET;
|
||||||
}
|
}
|
||||||
} catch (CodingException ex) {
|
} catch (CodingException ex) {
|
||||||
@ -880,7 +889,12 @@ public final class BearerData {
|
|||||||
private static String decode7bitGsm(byte[] data, int offset, int numFields)
|
private static String decode7bitGsm(byte[] data, int offset, int numFields)
|
||||||
throws CodingException
|
throws CodingException
|
||||||
{
|
{
|
||||||
String result = GsmAlphabet.gsm7BitPackedToString(data, offset, numFields);
|
int paddingBits = calcUdhSeptetPadding(offset);
|
||||||
|
numFields -= (((offset * 8) + paddingBits) / 7);
|
||||||
|
// TODO: It seems wrong that only Gsm7 bit encodings would
|
||||||
|
// take into account the header in numFields calculations.
|
||||||
|
// This should be verified.
|
||||||
|
String result = GsmAlphabet.gsm7BitPackedToString(data, offset, numFields, paddingBits);
|
||||||
if (result == null) {
|
if (result == null) {
|
||||||
throw new CodingException("7bit GSM decoding failed");
|
throw new CodingException("7bit GSM decoding failed");
|
||||||
}
|
}
|
||||||
|
@ -108,6 +108,21 @@ public class CdmaSmsTest extends AndroidTestCase {
|
|||||||
userData.payloadStr = "More @ testing\nis great^|^~woohoo";
|
userData.payloadStr = "More @ testing\nis great^|^~woohoo";
|
||||||
revBearerData = BearerData.decode(BearerData.encode(bearerData));
|
revBearerData = BearerData.decode(BearerData.encode(bearerData));
|
||||||
assertEquals(userData.payloadStr, revBearerData.userData.payloadStr);
|
assertEquals(userData.payloadStr, revBearerData.userData.payloadStr);
|
||||||
|
SmsHeader.ConcatRef concatRef = new SmsHeader.ConcatRef();
|
||||||
|
concatRef.refNumber = 0xEE;
|
||||||
|
concatRef.msgCount = 2;
|
||||||
|
concatRef.seqNumber = 2;
|
||||||
|
concatRef.isEightBits = true;
|
||||||
|
SmsHeader smsHeader = new SmsHeader();
|
||||||
|
smsHeader.concatRef = concatRef;
|
||||||
|
byte[] encodedHeader = SmsHeader.toByteArray(smsHeader);
|
||||||
|
userData.userDataHeader = smsHeader;
|
||||||
|
revBearerData = BearerData.decode(BearerData.encode(bearerData));
|
||||||
|
assertEquals(userData.payloadStr, revBearerData.userData.payloadStr);
|
||||||
|
SmsHeader decodedHeader = revBearerData.userData.userDataHeader;
|
||||||
|
assertEquals(decodedHeader.concatRef.refNumber, concatRef.refNumber);
|
||||||
|
assertEquals(decodedHeader.concatRef.msgCount, concatRef.msgCount);
|
||||||
|
assertEquals(decodedHeader.concatRef.seqNumber, concatRef.seqNumber);
|
||||||
}
|
}
|
||||||
|
|
||||||
@SmallTest
|
@SmallTest
|
||||||
|
Reference in New Issue
Block a user