Skip to content

Commit 6e69c26

Browse files
authored
Merge pull request #42 from tomchy/pr/pdu-timezone-fix
Handle invalid timezone values
2 parents 459159f + 2849814 commit 6e69c26

2 files changed

Lines changed: 44 additions & 27 deletions

File tree

gsmmodem/pdu.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -73,12 +73,12 @@ def _setPduOffsetStr(self, pduOffsetStr):
7373
# - Read HEX value as decimal
7474
# - Multiply by 15
7575
# See: https://en.wikipedia.org/wiki/GSM_03.40#Time_Format
76-
try:
77-
tzOffsetMinutes = int('{0:0>2X}'.format(tzHexVal & 0x7F)) * 15
78-
except:
79-
# Possible fix for #15
80-
tzHexVal = int((tzHexVal & 0x0F) * 0x10) + int((tzHexVal & 0x0F) / 0x10)
81-
tzOffsetMinutes = int('{0:0>2X}'.format(tzHexVal & 0x7F)) * 15
76+
77+
# Possible fix for #15 - convert invalid character to BCD-value
78+
if (tzHexVal & 0x0F) > 0x9:
79+
tzHexVal +=0x06
80+
81+
tzOffsetMinutes = int('{0:0>2X}'.format(tzHexVal & 0x7F)) * 15
8282

8383
if tzHexVal & 0x80 == 0: # positive
8484
self._offset = timedelta(minutes=(tzOffsetMinutes))

test/test_modem.py

Lines changed: 38 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -2210,31 +2210,48 @@ def writeCallbackFunc3(data):
22102210
time.sleep(0.1)
22112211
self.modem.close()
22122212

2213-
def test_receiveSmsPduMode_zeroLengthSmscAndHugeTimeZoneValue(self):
2213+
def test_receiveSmsPduMode_invalidPDUsRecordedFromModems(self):
22142214
""" Test receiving PDU-mode SMS using data captured from failed operations/bug reports """
2215-
modemResponse = ['+CMGR: 1,,26\r\n', '0006230E9126983575169498610103409544C26101034095448200\r\n', 'OK\r\n']
2215+
tests = ((['+CMGR: 1,,26\r\n', '0006230E9126983575169498610103409544C26101034095448200\r\n', 'OK\r\n'], # see: babca/python-gsmmodem#15
2216+
Sms.STATUS_RECEIVED_READ, # message read status
2217+
'+62895357614989', # number
2218+
35, # reference
2219+
datetime(2016, 10, 30, 4, 59, 44, tzinfo=SimpleOffsetTzInfo(8)), # sentTime
2220+
datetime(2016, 10, 30, 4, 59, 44, tzinfo=SimpleOffsetTzInfo(7)), # deliverTime
2221+
StatusReport.DELIVERED), # delivery status
2222+
)
22162223

2217-
callbackInfo = [False, '', '', -1, None, '', None]
2218-
def smsCallbackFunc1(sms):
2219-
try:
2220-
self.assertIsInstance(sms, gsmmodem.modem.StatusReport)
2221-
self.assertEqual(sms.status, gsmmodem.modem.Sms.STATUS_RECEIVED_READ)
2222-
finally:
2223-
callbackInfo[0] = True
2224+
callbackDone = [False]
22242225

2225-
def writeCallback1(data):
2226-
if data.startswith('AT+CMGR'):
2227-
self.modem.serial.flushResponseSequence = True
2228-
self.modem.serial.responseSequence = modemResponse
2226+
for modemResponse, msgStatus, number, reference, sentTime, deliverTime, deliveryStatus in tests:
2227+
def smsCallbackFunc1(sms):
2228+
try:
2229+
self.assertIsInstance(sms, gsmmodem.modem.StatusReport)
2230+
self.assertEqual(sms.status, msgStatus, 'Status report read status incorrect. Expected: "{0}", got: "{1}"'.format(msgStatus, sms.status))
2231+
self.assertEqual(sms.number, number, 'SMS sender number incorrect. Expected: "{0}", got: "{1}"'.format(number, sms.number))
2232+
self.assertEqual(sms.reference, reference, 'Status report SMS reference number incorrect. Expected: "{0}", got: "{1}"'.format(reference, sms.reference))
2233+
self.assertIsInstance(sms.timeSent, datetime, 'SMS sent time type invalid. Expected: datetime.datetime, got: {0}"'.format(type(sms.timeSent)))
2234+
self.assertEqual(sms.timeSent, sentTime, 'SMS sent time incorrect. Expected: "{0}", got: "{1}"'.format(sentTime, sms.timeSent))
2235+
self.assertIsInstance(sms.timeFinalized, datetime, 'SMS finalized time type invalid. Expected: datetime.datetime, got: {0}"'.format(type(sms.timeFinalized)))
2236+
self.assertEqual(sms.timeFinalized, deliverTime, 'SMS finalized time incorrect. Expected: "{0}", got: "{1}"'.format(deliverTime, sms.timeFinalized))
2237+
self.assertEqual(sms.deliveryStatus, deliveryStatus, 'SMS delivery status incorrect. Expected: "{0}", got: "{1}"'.format(deliveryStatus, sms.deliveryStatus))
2238+
self.assertEqual(sms.smsc, None, 'This SMS should not have any SMSC information')
2239+
finally:
2240+
callbackDone[0] = True
22292241

2230-
self.initModem(smsStatusReportCallback=smsCallbackFunc1)
2231-
# Fake a "new message" notification
2232-
self.modem.serial.writeCallbackFunc = writeCallback1
2233-
self.modem.serial.flushResponseSequence = True
2234-
self.modem.serial.responseSequence = ['+CDSI: "SM",1\r\n']
2235-
# Wait for the handler function to finish
2236-
while callbackInfo[0] == False:
2237-
time.sleep(0.1)
2242+
def writeCallback1(data):
2243+
if data.startswith('AT+CMGR'):
2244+
self.modem.serial.flushResponseSequence = True
2245+
self.modem.serial.responseSequence = modemResponse
2246+
2247+
self.initModem(smsStatusReportCallback=smsCallbackFunc1)
2248+
# Fake a "new message" notification
2249+
self.modem.serial.writeCallbackFunc = writeCallback1
2250+
self.modem.serial.flushResponseSequence = True
2251+
self.modem.serial.responseSequence = ['+CDSI: "SM",1\r\n']
2252+
# Wait for the handler function to finish
2253+
while callbackDone[0] == False:
2254+
time.sleep(0.1)
22382255

22392256

22402257

0 commit comments

Comments
 (0)