How To Get Allowed Maximum Length For An Sms?
I'm coding an Android APK to manage GPS trackers by SMS. My software has a special notification part that decodes all alarms that device sends via SMS messages. Problem is that som
Solution 1:
As this is a very convoluted matter and requires piecing together different parts of standards and protocols, I've decided to post all the info I've found for whoever needs to solve this issue like me.
All checks should be done in PDU data directly, accessing bits and bytes, either within SmsMessage with getPdu()
or directly accessing the PDU
array from Bundle in onReceive()
of your SMS BroadcastReceiver
.
First of all, we need to check two things for detecting a multi-part SMS:
- Presence of
IDH
, bit 6 inPDU_TYPE
- Presence of multipart indicator in
IDH
, second byte ofUDH
info
After detecting a multi-part message we need to identify messages belonging to same multi-part by checking CSMS identifier, number of parts and part index.
/**
* EXAMPLE OF A PDU
*
* 07 length of SMSC info in bytes
* 91 type of address
* 551218317600 SMSC address (variable size)
* 04 PDU_TYPE to check for IDH embedded test bit 6 0=not UDH 1=has UDH
* 0B address length in nibbles, here is 11 nibbles so its 6 bytes
* 81 address type
* 1089920478F1 sender number (variable size)
* 00 TP-PID
* 08 TP-DCS
* 31105161225188 TP-SCTS timestamp
* 38 TP-UDL user data length
* [USER DATA STARTS HERE] When UDH info is embedded, starts in first
* bytes of user data
*
* EXAMPLE OF UDH for 8 bit CSMS reference (unique number, indicates
* parts belong to same message)
*
* 05 UDH length in bytes
* 00 For multipart 8 bits CSMS it is 00, for 16bits CSMS it is 08
* 03 length of header
* 48 CSMS reference number, this identify SMSs that belong
* to same multi-part
* 02 total parts of this sequence (in this case, 2 parts)
* 02 sequence number (in this case, 2 of 2)
*
*
* EXAMPLE OF UDH for 16 bit CSMS reference (unique number, indicates
* parts belong to same message)
*
* 06 UDH length in bytes
* 00 For multipart 8 bits CSMS it is 00, for 16bits CSMS it is 08
* 04 length of header
* 4823 16 bits CSMS reference number, this identify SMSs that belong
* to the same multi-part
* 02 total parts of this sequence (in this case, 2 parts)
* 01 sequence number (in this case, 1 of 2)
*
*/// SOME HELPERS TO CHECK FOR MULTIPART INSIDE PDUprivatefinal byte UDH_BITMASK = 0x60;
privatefinal byte MULTIPART_8BITSEQ = 0x00;
privatefinal byte MULTIPART_16BITSEQ = 0x08;
privatefinalint TP_ADDLENGTH_LEN=1;
privatefinalint TP_ADDTYPE_LEN=1;
privatefinalint TP_PID_LEN=1;
privatefinalint TP_DCS_LEN=1;
privatefinalint TP_SCTS_LEN=7;
privatefinalint TP_UDL_LEN=1;
/**
* Check if this PDU message is multi part
* @param pdu
* @return
*/privateboolean isMultiPart(byte[] pdu)
{
// get length of first part+1 SMSC index to PDU typeint idx= pdu[0]+TP_ADDLENGTH_LEN;
if((pdu[idx] & UDH_BITMASK) != 0) // has UDH ??
{
// 00=length of UDH 01=typeint udataidx = getUserDataIndex(pdu);
if( (pdu[udataidx+1] == MULTIPART_8BITSEQ)
|| (pdu[udataidx+1] == MULTIPART_16BITSEQ))
returntrue;
}
returnfalse;
}
/**
* Return index for user data part. Used to retrieve UDH info
* @param pdu
* @return
*/privateint getUserDataIndex(byte[] pdu)
{
// get index to ADDRESS lengthint idx=pdu[0]+ TP_ADDLENGTH_LEN + TP_ADDTYPE_LEN;
// get length in nibblesint oalength = pdu[idx];
// convert to bytes with padding for odd valuesint oalengthinbytes = (oalength + 1) / 2;
return(idx + TP_ADDLENGTH_LEN + TP_ADDTYPE_LEN + oalengthinbytes +
TP_PID_LEN + TP_DCS_LEN + TP_SCTS_LEN + TP_UDL_LEN);
}
Post a Comment for "How To Get Allowed Maximum Length For An Sms?"