SMS,EMS PDU Code Decoder 短信PDU格式解码器

类别:.NET开发 点击:0 评论:0 推荐:

'==========================================================
'                    SMS,EMS Decoder
'                      2004-9-24
'1.Description
'   This class decode a SMS or EMS PDU code to a certain
'class. You can use it in your software to read SMSs and
'EMSs. All of this is done under GSM 03.40. I tested it
'on my SIEMENS M55 and NOKIA 8xxx and it works well.
'2.Useage
'   If you know what type of PDU code, you can create a
'new instance of class like DIM s as SMS(myPDUCode)
'When instance is created, you read its public variable
'to get what you want.
'   When TP_DCS=0, PDU code is coded from 7bit
'charactor (see GSM 03.38), use shared function
'Deocde7Bit to decode it.
'   When TP_DCS=8, PDU code is coded from Unicode
'charactor (see GSM 03.38), use shared funtion
'DecodeUnicode to decode it.
'3.Bugs
'   So far in my tests I found none.
'4.When you use it
'   You can freely use it or modify it in your program,
'but when you find bugs or improved it please publish it
'or send one copy to me. Thanks
'5.About me
'   I am writting a program which can list folders and
'files in SIEMENS M55 mobile phone. It can also read
'and send SMS,EMS. Some documents are hard to find on
'internet, but I keep on my mind to study it and finally
'I found it is full of interests.
'    I like freedom, so'I exchange my ideas with all of
'the world. It is so happy that you can use my classes!
'   In the end, sorry for my poor english.
'6.Contact me
'   Email:[email protected]
'   QQ:38288890
'   Homepage:http://hesicong2004.vip.myrice.com (Chinese)
'                       ----By HESICONG
'Last edited 2004-9-24

Public MustInherit Class SMS
    Public SCAddressLength As Byte
    Public SCAddressType As Byte
    Public SCAddressValue As String
    Public FirstOctet As Byte
    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 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

    Public MustOverride Sub GetOrignalData(ByVal PDUCode As String)

    'Get a byte from PDU string
    Shared Function GetByte(ByRef PDUCode As String) As Byte
        Dim r As Byte = Val("&H" + Mid(PDUCode, 1, 2))
        PDUCode = Mid(PDUCode, 3)
        Return r
    End Function

    'Get a string of certain length
    Shared Function GetString(ByRef PDUCode As String, ByVal Length As Integer) As String
        Dim r As String = Mid(PDUCode, 1, Length)
        PDUCode = Mid(PDUCode, Length + 1)
        Return r
    End Function

    'Get date from SCTS format
    Shared Function GetDate(ByRef SCTS As String) As Date
        Dim year, month, day, hour, minute, second, timezone As Integer

        year = Val(Swap(GetString(SCTS, 2))) + 2000
        month = Val(Swap(GetString(SCTS, 2)))
        day = Val(Swap(GetString(SCTS, 2)))
        hour = Val(Swap(GetString(SCTS, 2)))
        minute = Val(Swap(GetString(SCTS, 2)))
        second = Val(Swap(GetString(SCTS, 2)))
        timezone = Val(Swap(GetString(SCTS, 2)))

        Dim result As New Date(year, month, day, hour, minute, second)
        Return result
    End Function

    'Swap two bit
    Shared Function Swap(ByRef TwoBitStr As String) As String
        Dim c() As Char = TwoBitStr.ToCharArray
        Dim t As Char
        t = c(0)
        c(0) = c(1)
        c(1) = t
        Return (c(0) + c(1)).ToString
    End Function

    'Get phone address
    Shared Function GetAddress(ByRef Address As String) As String
        Dim tmpChar As Char() = Address.ToCharArray
        Dim i As Integer, result As String
        For i = 0 To tmpChar.GetUpperBound(0) Step 2
            result += Swap(tmpChar(i) + tmpChar(i + 1))
        Next
        If InStr(result, "F") Then result = Mid(result, 1, result.Length - 1)
        Return result
    End Function


    Shared Function GetSMSType(ByVal PDUCode As String) As SMS.SMSType
        'Get first october
        Dim FirstOctet As Byte
        Dim L As Integer = SMS.GetByte(PDUCode)
        SMS.GetByte(PDUCode)
        SMS.GetString(PDUCode, (L - 1) * 2)
        FirstOctet = SMS.GetByte(PDUCode)
        '[Chinese]取得特征码
        '[Chinese]取得基本码 最后两个bit + 是否有header作为标记
        'Get base code. Use last 2 bit and whether there's a header as remark
        Dim t1 As Integer = FirstOctet And 3 '00000011
        Dim t2 As Integer = FirstOctet And 64 '01000000
        '[Chinese]特别处理
        If t1 = 3 And t2 = 64 Then Return SMS.SMSType.EMS_SUBMIT
        Return t1 + t2
    End Function

    'Deoce a unicode string
    Shared Function DecodeUnicode(ByVal strUnicode As String) As String
        Dim Code As String
        Dim i, j As Integer
        Dim c() As String       'temp
        ReDim c(strUnicode.Length / 4)     '2 Byte a Unicode char

        For j = 0 To strUnicode.Length \ 4 - 1
            Dim d() As Char = strUnicode.ToCharArray(j * 4, 4)
            c(j) = "&H" & CType(d, String)
            c(j) = ChrW(Val(c(j)))
            Code += c(j)
        Next
        Return Code
    End Function

    'Deocde 7Bit to english
    Shared Function Deocde7Bit(ByVal str7BitCode As String) As String
        Dim i, j As Integer
        Dim Result As String
        Dim tmpChar As Char() = str7BitCode.ToCharArray
        Dim Dec, m, CharAscii, Reminder, t As Integer
        Do Until j > tmpChar.GetUpperBound(0)
            i = i Mod 7
            Dec = Val("&H" & tmpChar(j) & tmpChar(j + 1))
            CharAscii = (Dec And (2 ^ (7 - i) - 1)) * 2 ^ i + Reminder
            Reminder = Dec \ 2 ^ (7 - i)
            Result += Chr(CharAscii)
            If i = 6 Then
                Result += Chr(Reminder)
                Reminder = 0
            End If
            i += 1
            j += 2
        Loop
        Return Result
    End Function
End Class

Public Class SMS_RECEIVED
    Inherits SMS
    Public SrcAddressLength As Byte
    Public SrcAddressType As Byte
    Public SrcAddressValue As String
    Public TP_SCTS As Date

    Sub New(ByVal PDUCode As String)
        Type = SMS.SMSType.SMS_RECEIVED
        GetOrignalData(PDUCode)
    End Sub
    Public Overrides Sub GetOrignalData(ByVal PDUCode As String)
        SCAddressLength = GetByte(PDUCode)
        SCAddressType = GetByte(PDUCode)
        SCAddressValue = GetAddress((GetString(PDUCode, (SCAddressLength - 1) * 2)))
        FirstOctet = GetByte(PDUCode)

        SrcAddressLength = GetByte(PDUCode)
        SrcAddressType = GetByte(PDUCode)
        SrcAddressLength += SrcAddressLength Mod 2
        SrcAddressValue = GetAddress((GetString(PDUCode, SrcAddressLength)))


        TP_PID = GetByte(PDUCode)
        TP_DCS = GetByte(PDUCode)
        TP_SCTS = GetDate(GetString(PDUCode, 14))
        TP_UDL = GetByte(PDUCode)
        TP_UD = GetString(PDUCode, TP_UDL * 2)
    End Sub
End Class

Public Class SMS_SUBMIT
    Inherits SMS
    Public TP_MR As Byte
    Public DesAddressLength As Byte
    Public DesAddressType As Byte
    Public DesAddressValue As String
    Public TP_VP As Byte
    Sub New(ByVal PDUCode As String)
        Type = SMS.SMSType.SMS_SUBMIT
        GetOrignalData(PDUCode)
    End Sub

    Public Overrides Sub GetOrignalData(ByVal PDUCode As String)
        SCAddressLength = GetByte(PDUCode)
        SCAddressType = GetByte(PDUCode)
        SCAddressValue = GetAddress((GetString(PDUCode, (SCAddressLength - 1) * 2)))
        FirstOctet = GetByte(PDUCode)

        TP_MR = GetByte(PDUCode)

        DesAddressLength = GetByte(PDUCode)
        DesAddressType = GetByte(PDUCode)
        DesAddressLength += DesAddressLength Mod 2
        DesAddressValue = GetAddress((GetString(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
End Class

Public Class EMS_RECEIVED
    Inherits SMS_RECEIVED
    Public Structure InfoElem       'See document "How to create EMS"
        Public Identifier As Byte
        Public Length As Byte
        Public Data As String
    End Structure
    Public TP_UDHL As Byte

    Public IE() As InfoElem

    Sub New(ByVal PDUCode As String)
        MyBase.New(PDUCode)
    End Sub
    Public Overrides Sub GetOrignalData(ByVal PDUCode As String)
        SCAddressLength = GetByte(PDUCode)
        SCAddressType = GetByte(PDUCode)
        SCAddressValue = GetAddress(GetString(PDUCode, (SCAddressLength - 1) * 2))
        FirstOctet = GetByte(PDUCode)

        SrcAddressLength = GetByte(PDUCode)
        SrcAddressType = GetByte(PDUCode)
        SrcAddressLength += SrcAddressLength Mod 2
        SrcAddressValue = GetAddress((GetString(PDUCode, SrcAddressLength)))

        TP_PID = GetByte(PDUCode)
        TP_DCS = GetByte(PDUCode)
        TP_SCTS = GetDate(GetString(PDUCode, 14))
        TP_UDL = GetByte(PDUCode)
        TP_UDHL = GetByte(PDUCode)

        IE = GetIE(GetString(PDUCode, TP_UDHL * 2))

        TP_UD = GetString(PDUCode, TP_UDL)
    End Sub

    'Get Informat Elements
    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
End Class

Public Class EMS_SUBMIT
    Inherits SMS_SUBMIT

    Sub New(ByVal PDUCode As String)
        MyBase.New(PDUCode)
        Type = SMS.SMSType.EMS_SUBMIT
    End Sub

    Public TP_UDHL As Byte

    Public IE() As EMS_RECEIVED.InfoElem


    Public Overrides Sub GetOrignalData(ByVal PDUCode As String)
        SCAddressLength = GetByte(PDUCode)
        SCAddressType = GetByte(PDUCode)
        SCAddressValue = GetAddress(GetString(PDUCode, (SCAddressLength - 1) * 2))
        FirstOctet = GetByte(PDUCode)

        TP_MR = GetByte(PDUCode)

        DesAddressLength = GetByte(PDUCode)
        DesAddressType = GetByte(PDUCode)
        DesAddressLength += DesAddressLength Mod 2
        DesAddressValue = GetAddress(GetString(PDUCode, DesAddressLength))

        TP_PID = GetByte(PDUCode)
        TP_DCS = GetByte(PDUCode)
        TP_VP = GetByte(PDUCode)
        TP_UDL = GetByte(PDUCode)

        TP_UDHL = GetByte(PDUCode)
        IE = EMS_RECEIVED.GetIE(GetString(PDUCode, TP_UDHL * 2))

        TP_UD = GetString(PDUCode, TP_UDL * 2)
    End Sub
End Class

Public Class SMS_STATUS_REPORT
    Inherits SMS_RECEIVED
    Public TP_MR As Byte
    Public TP_DP As Date
    Public Status As Byte
    Sub New(ByVal PDUCode As String)
        MyBase.New(PDUCode)
        Type = SMS.SMSType.SMS_STATUS_REPORT
    End Sub
    Public Overrides Sub GetOrignalData(ByVal PDUCode As String)
        SCAddressLength = GetByte(PDUCode)
        SCAddressType = GetByte(PDUCode)
        SCAddressValue = GetAddress(GetString(PDUCode, (SCAddressLength - 1) * 2))

        FirstOctet = GetByte(PDUCode)

        TP_MR = GetByte(PDUCode)

        SrcAddressLength = GetByte(PDUCode)
        SrcAddressType = GetByte(PDUCode)
        SrcAddressLength += SrcAddressLength Mod 2
        SrcAddressValue = GetAddress(GetString(PDUCode, SrcAddressLength))

        TP_SCTS = GetDate(GetString(PDUCode, 14))
        TP_DP = GetDate(GetString(PDUCode, 14))

        Status = GetByte(PDUCode)

        'Status report do not have content so I set it a zero length string
        TP_UD = ""
    End Sub
End Class

本文地址:http://com.8s8s.com/it/it43969.htm