Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

PDU Decoding Error #99

Open
mwfong-csl opened this issue Nov 5, 2021 · 1 comment
Open

PDU Decoding Error #99

mwfong-csl opened this issue Nov 5, 2021 · 1 comment

Comments

@mwfong-csl
Copy link

mwfong-csl commented Nov 5, 2021

gsmmodem/pdu.py:_decodeUserData () unconditionally skips the first character of any PDU that contains UDH fields.

def _decodeUserData(byteIter, userDataLen, dataCoding, udhPresent):
    """ Decodes PDU user data (UDHI (if present) and message text) """
    result = {}
    if udhPresent:
        # User Data Header is present
        result['udh'] = []
        udhLen = next(byteIter)
        ieLenRead = 0
        # Parse and store UDH fields
        while ieLenRead < udhLen:
            ie = InformationElement.decode(byteIter)
            ieLenRead += len(ie)
            result['udh'].append(ie)
        del ieLenRead
        if dataCoding == 0x00: # GSM-7
            # Since we are using 7-bit data, "fill bits" may have been added to make the UDH end on a septet boundary
            shift = ((udhLen + 1) * 8) % 7 # "fill bits" needed to make the UDH end on a septet boundary
            # Simulate another "shift" in the unpackSeptets algorithm in order to ignore the fill bits
            prevOctet = next(byteIter)
            shift += 1
    :
    :

should be

def _decodeUserData(byteIter, userDataLen, dataCoding, udhPresent):
    """ Decodes PDU user data (UDHI (if present) and message text) """
    result = {}
    if udhPresent:
        # User Data Header is present
        result['udh'] = []
        udhLen = next(byteIter)
        ieLenRead = 0
        # Parse and store UDH fields
        while ieLenRead < udhLen:
            ie = InformationElement.decode(byteIter)
            ieLenRead += len(ie)
            result['udh'].append(ie)
        del ieLenRead
        if dataCoding == 0x00: # GSM-7
            # Since we are using 7-bit data, "fill bits" may have been added to make the UDH end on a septet boundary
            shift = ((udhLen + 1) * 8) % 7 # "fill bits" needed to make the UDH end on a septet boundary
            # Simulate another "shift" in the unpackSeptets algorithm in order to ignore the fill bits
            if shift:
                prevOctet = next(byteIter)
                shift += 1
            else:
                prevOctet = 0
    :
    :

This online SMS PDU decoder correctly decodes the following PDU, but _decodeUserData () does not:

07912160130350F66003C916F100009170914115628AA0060804931802015474D8BD9E83CC6F39482C4FBBCF69F719947FD7E52038FAED2E83E86F50B34C97BF41E23C88DA6ABEC569763904B2A6E7693A084DA7C375AF57BB4C97BFE1E3B92BFD7E09A3EDF3710A0ABBC9A073990EA2A3CBA066BE59A6CBDFA0301C0E9ABF41F9771D340EBB41EDB03B7C2E83F2EFBA1C141E8FDF75371D14769341EDF0BA0C1AA3C3

Test code:

import gsmmodem.pdu as pdu

_smsIn = [
    '+CMGL: 0,0,,155',
    '07912160130350F66003C916F100009170914115628AA0060804931802015474D8BD9E83CC6F39482C4FBBCF69F719947FD7E52038FAED2E83E86F50B34C97BF41E23C88DA6ABEC569763904B2A6E7693A084DA7C375AF57BB4C97BFE1E3B92BFD7E09A3EDF3710A0ABBC9A073990EA2A3CBA066BE59A6CBDFA0301C0E9ABF41F9771D340EBB41EDB03B7C2E83F2EFBA1C141E8FDF75371D14769341EDF0BA0C1AA3C3',
    '+CMGL: 1,0,,48',
    '07912160130350F66003C916F100009170914115728A2506080493180202EE73790E92A7CF683AC82C7FB741F9775D0E4287DDE479991E02',
    'OK'
]

for _i in range (1, len (_smsIn) - 1, 2):
    print (pdu.decodeSmsPdu (_smsIn[_i]))

Results:

#
# Original gsmmodem/pdu.py:_decodeUserData ()
#
% python3 pduDecodeBug.py 
{'smsc': '+12063130056', 'tpdu_length': 155, 'type': 'SMS-DELIVER', 'number': '611', 'protocol_id': 0, 'time': datetime.datetime(2019, 7, 19, 14, 51, 26, tzinfo=<gsmmodem.pdu.SmsPduTzInfo object at 0x10517fcc0>), 'udh': [<gsmmodem.pdu.Concatenation object at 0x1046e3ef0>], 'text': 'hanks for bringing your phone to Metro by T-Mobile! Visit http://metropcs.io/BQmgGS and get the MyMetro app so you can manage your account and make cha'}
{'smsc': '+12063130056', 'tpdu_length': 48, 'type': 'SMS-DELIVER', 'number': '611', 'protocol_id': 0, 'time': datetime.datetime(2019, 7, 19, 14, 51, 27, tzinfo=<gsmmodem.pdu.SmsPduTzInfo object at 0x104700240>), 'udh': [<gsmmodem.pdu.Concatenation object at 0x1046e3f60>], 'text': 'ges right from your handset!'}

#
# Corrected gsmmodem/pdu.py:_decodeUserData ()
#
% python3.7 pduDecodeBug.py 
{'smsc': '+12063130056', 'tpdu_length': 155, 'type': 'SMS-DELIVER', 'number': '611', 'protocol_id': 0, 'time': datetime.datetime(2019, 7, 19, 14, 51, 26, tzinfo=<gsmmodem.pdu.SmsPduTzInfo object at 0x10fcc4390>), 'udh': [<gsmmodem.pdu.Concatenation object at 0x10fccf470>], 'text': 'Thanks for bringing your phone to Metro by T-Mobile! Visit http://metropcs.io/BQmgGS and get the MyMetro app so you can manage your account and make cha'}
{'smsc': '+12063130056', 'tpdu_length': 48, 'type': 'SMS-DELIVER', 'number': '611', 'protocol_id': 0, 'time': datetime.datetime(2019, 7, 19, 14, 51, 27, tzinfo=<gsmmodem.pdu.SmsPduTzInfo object at 0x10fb4a7b8>), 'udh': [<gsmmodem.pdu.Concatenation object at 0x10fb4a6d8>], 'text': 'nges right from your handset!'}
@JimJty
Copy link

JimJty commented Jan 5, 2022

I ran into this issue as well. I'm testing the fix for my service, but looks to be working so far.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants