(10) SMS section - VB.NET decoding PDU
As early as January 2004, I started to initially study the principle of coding decoding of PDU, and there is also a relatively deep understanding of PDU. Then I wrote a PDU decoder according to the 3GPP protocol, and later written as a PDU decoder article on the bottom of CodeProject. There are a few good foreign netizens to point some bugs, now there is a relatively perfect decoder. The specific source code is at http://blog.9cbs.net/HESICONG/Archive/2004/09/24/115356.aspx. This article explains the composition of the encoder and the decoding methods and techniques I use.
Polymerization of the decoder
Namespace SMS
Decoder
Mustinheritclass SMSBase
Class EMS_RECEIVED
Class EMS_SUBMIT
Class SMS_Received
Class SMS_STATUS_REPORT
Class SMS_SUBMIT
Class PDudecoder
SMSBase section
The SMSBase class is a must inherited class, which contains the basic structure of the PDU and some related auxiliary functions. It is the most basic class, and other classes are inherited from SMSBase. The type of PDU can be obtained by SMSBase's Shared function getSmstype to determine the use of Class.
SMSBase contains the basic information section of all SMS types and a enumeration SMSTYPE indicating the SMS type, inherits the basic information section of its unique.
Public SCADDRESSLENGTH AS BYTE 'Service Center Address LENGTH
Public scaddresstype as byte '
Service
Center
Type [see gsm 03.40]
Public ScaddressValue as string '
Service
Center
NUBER
Public firstoctet as byte 'See GSM 03.40
Public tp_pid as byte
Public TP_DCS as Byte
Public TP_UDL AS BYTE
Public TP_UD AS STRING
Public text As string, PUBLIC TEXT AS STRING
Public Type As SMSTYPE
Public UserData As String
Public enum smstype
SMS_Received = 0
SMS_STATUS_REPORT = 2
SMS_SUBMIT = 1
EMS_RECEIVED = 64 'IT IS "reserved" on my phone ??
EMS_SUBMIT = 65
END ENUM
A process GetORIGNALDATA that must be rewritten is defined in SMSBase, which is the purpose of obtaining basic information of the PDU. Different SMS types have different decoding processes, so as a function that must be rewritten.
Public Mustoverride Sub getorignaldata (Byval Pducode As String)
There is also a series of secondary auxiliary functions in SMSBase, and the specific implementation method is available:
Processing the PDU code:
Processing PDU code I use skills that claim to "on demand", that is, extract the required data, then remove this part from the original PDucode, and processes the next function. This does not have to adopt the specific offset, simplify the operation, enhance the adaptability. In order to reduce the trouble of returning, I use Byref. After the execution process, PDucode is automatically reduced. 'Get a byte from PDU String
Shared function getByte (byref pducode as string) AS BYTE
'Get a string of ceertling
Shared function getString (byref pducode as string, byval length as integer) AS STRING
'Get Date from SCTS Format
Shared function getdate (byref SCTS AS STRING) AS Date
'Swap Two Bit
Shared function swap (byref twobitstr as string) AS String
'Get Phone Address
Shared function getaddress (byref address as string) AS String
Shared function getSmstype (byval pducode as string) as smsbase.smstype
TP-UD decoding section:
The task of the decoding of the TP-UD is mainly concentrated in Unicode decoding and 7bitCode decoding. Where Unicode's decoding is convenient, just convert the two bytes of PDucode into numbers through the VAL function, and can be obtained by the ChRW function.
The 7bitcode is more difficult. The following is briefly introduced by TEST four characters. For details, please refer to the relevant information.
BYTE1 11010100 0xD4
BYTE2 11110010 0xF2
Byte3 10011100 0X
9C
BYTE4 00001110 0x0E
Note: Each character binary code:
T: 1010100 E: 1100101 S: 1110011 T: 1110100
From this example, it can be seen that a BYTE contains a binary part of the ASCII code of a character and the low position of the binary part of the subsequent characters. Such 8 characters can be compressed into 7 Byte, and 140by TP-UD length can accommodate 160 English letters in the SMS.
It can be seen from the observation that as long as we splicing all the binary code to a piece beforewards, the above example is obtained by splicing:
00001110100111001111001011010100
We can directly intercept the decoded code directly by intercepting the principles of 7 sets from the previous group. For the convenience of programming, I have designed a simple and easy to understand, which is simpler than the comparation of the multi-multiplication method, but the final efficiency is not as it. But I want to apply in ordinary situations.
1, decode7bit get a PDU TP-UD section
2, InvertHexString reversal hexadecimal code: for example 123456 => 563412
3, binary string to get the binary representation of the hexadecimal code after reverse. Note that the string is still used to represent binary, in order to facilitate "splicing" and "cutting"
4, according to the number of characters provided by CharCount (from TP_UDL), press 7 sets from the character crosses, and converted to the ASCII with the CHR function. Here are some of the statement of some functions, please refer to the PDudecoder in Blog.
'DEOCE A Unicode String
Shared function decodeunicode (Byval Strunicode As String) AS STRING
'Decode 7bit TO ENGLISH
Shared function inverthexstring (byval hexstring as string) AS String
Shared function bytetobinary (byval dec as byte) AS STRING
Shared function binarytoint (byval binary as string) AS Integer
Shared function decode7bit (byval str7bitcode as string, byval charcount as integer) AS String
SMS_SUBMIT, SMS_RECEIVED, SMS_STATUS_REPORT
Since SMS_Received, SMS_STATUS_REPORT is similar to SMS_Submit, so I focus on SMS_SUBMIT.
When a PDUCode is determined using a PDUCode as SMS_SUBMIT with SMSBase, you can declare an instance of an SMS_SUBMIT class, by passing this PDUCode as a parameter of the constructor. The constructor immediately calls the getorignaldata function decoding.
The reference protocol knows that SMS_SUBMIT is more than SMSBase:
Public TP_MR AS BYTE
Public DesaddressLength As Byte
Public DesaddressType as Byte
Public DesaddressValue As String
Public TP_VP as Byte
Reference Agreement We can easily get the achievement of the getorignaldata function:
Public overrides sub getorignaldata (Byval Pducode As String)
ScaddressLength = GetByte (PDucode)
SCADDRESSTYPE = GetByte (PDucode)
ScaddressValue = Getdress ((GetString (pducode, (ScaddressLength - 1) * 2))))))))))
FirstOCTET = GetByte (PDucode)
TP_MR = GetByte (PDucode)
DesaddressLength = GetByte (PDucode)
DesaddressType = getByte (pducode)
DesaddressLength = desaddressLength Mod 2
DesaddressValue = GetDress ((pducode, desaddressLength)))
TP_PID = GetByte (PDucode)
TP_DCS = GetByte (PDucode)
TP_VP = GetByte (PDucode)
TP_UDL = GetByte (PDucode)
TP_UD = GetString (Pducode, TP_UDL * 2)
End Sub
This completes the entire decoding process, and this decoding process is simple and convenient to pass the SMSBase.
EMS_SUBMIT, EMS_RECEIVED For EMS (Enhanced SMS), its basic structure and SMS are similar, the main difference is Information Element (IE). So EMS_SUBMIT inherits SMS_SUBMIT, EMS_RECEIVED inherits SMS_Received
Refer to the 3GPP protocol EMS section we can make the following structures and definitions
Public Structure Infoelem 'See Document "How to create" HOW CREATE
EMS
"
Public Identifier as Byte
Public Length as Byte
Public Data As String
End structure
Public TP_UDHL AS BYTE
In order to get IE I wrote a function:
Shared function getie (Byval IECode As String) AS Infoelem ()
DIM TMP As String = IECode, T as integer = 0
Dim Result () AS Infoelem
Do Until IECode = ""
Redim Preserve Result (T)
WITH RESULT (T)
.Identifier = GetByte (IECode)
.Length = getByte (IECODE)
.DATA = getString (IECode, .length * 2)
End with
T = 1
Loop
Return RESULT
END FUNCTION
The reference protocol can then write the getorignaldata function. It will not be described in terms.
PDudecoder
This class consists of a structure, an important decoding function.
The structure defines the basic information that needs to be obtained, and it can be modified as needed. I provide an example here.
Public structure baseinfo
Public SourceNumber As String
Public DestinationNumber As String
Public ReceivedDate as date
Public text As string, PUBLIC TEXT AS STRING
Public Type as sms.decoder.smsbase.smstype
Public Emstotolpiece As Integer
Public EMSCURRENTPIECE AS INTEGER
Public StatusFromReport As SMS_STATUS_REPORT.ENUMSTATUS
Public DestinationReceiveddate
End structure
The declaration of the decoding function is as follows:
Public Shared Function Decode (Byval Pducode As String) AS BaseInfo
The internal main processing steps are as follows (source code, please refer to PDudecoder)
1. Get SMS type SmStype according to the SMSBase's getSmstype function
2. Example of the corresponding class according to the SMSTYPE
3. Decoding the PDU to get the basic structure
4. Get the data needed in the Baseinfo structure by the basic structure
5. Get tp_UD data via decode7bit or decodeunicore function
So far, this is a detailed introduction of the entire PDU Decoder, and the specific use can be found in the relevant section of the Siemens Support Tool, and details will not be described here.