1*9c5db199SXin Li# Lint as: python2, python3 2*9c5db199SXin Li# Copyright (c) 2011 The Chromium OS Authors. All rights reserved. 3*9c5db199SXin Li# Use of this source code is governed by a BSD-style license that can be 4*9c5db199SXin Li# found in the LICENSE file. 5*9c5db199SXin Li 6*9c5db199SXin Lifrom __future__ import absolute_import 7*9c5db199SXin Lifrom __future__ import division 8*9c5db199SXin Lifrom __future__ import print_function 9*9c5db199SXin Li 10*9c5db199SXin Liimport dbus, logging 11*9c5db199SXin Li 12*9c5db199SXin Lifrom six.moves import zip 13*9c5db199SXin Li 14*9c5db199SXin Lifrom autotest_lib.client.common_lib import error 15*9c5db199SXin Li 16*9c5db199SXin Lisample = { 17*9c5db199SXin Li 'pdu' : 18*9c5db199SXin Li '07914140540510F0040B916171056429F500001190804181106904D4F29C0E', 19*9c5db199SXin Li 'parsed' : 20*9c5db199SXin Li {'text' : 'Test', 21*9c5db199SXin Li 'number' : '+16175046925', 22*9c5db199SXin Li 'timestamp' : '110908141801-04', 23*9c5db199SXin Li 'smsc' : '+14044550010' 24*9c5db199SXin Li } 25*9c5db199SXin Li } 26*9c5db199SXin Li 27*9c5db199SXin Lisample_multipart = { 28*9c5db199SXin Li 'pdu' : 29*9c5db199SXin Li ['07912160130320F8440B916171056429F5000011909161037469A0050003920201A9' 30*9c5db199SXin Li 'E5391DF43683E6EF7619C47EBBCF207A194F0789EB74D03D4D47BFEB7450D89D0791' 31*9c5db199SXin Li 'D366737A5C67D3416374581E1ED3CBF23928ED1EB3EBE43219947683E8E832A85D9E' 32*9c5db199SXin Li 'CFC3E7B20B4445A7E72077B94C9E83E86F90B80C7ADBCB72101D5D06B1CBEE331D0D' 33*9c5db199SXin Li 'A2A3E5E539FACD2683CC6F39888E2E83D8EF71980D9ABFCDF47B585E06D1DF', 34*9c5db199SXin Li '07912160130320F5440B916171056429F50000119091610384691505000392020241' 35*9c5db199SXin Li 'E437888E2E83E670769AEE02'], 36*9c5db199SXin Li 'parsed' : 37*9c5db199SXin Li {'text' : 'Test of some long text but without any difficult characters' 38*9c5db199SXin Li ' included in the message. This needs to be over the length threshold' 39*9c5db199SXin Li ' for the local software to do the split.', 40*9c5db199SXin Li 'number' : '+16175046925', 41*9c5db199SXin Li 'timestamp' : '110919163047-04', 42*9c5db199SXin Li 'smsc' : '+12063130028' 43*9c5db199SXin Li } 44*9c5db199SXin Li } 45*9c5db199SXin Li 46*9c5db199SXin Li 47*9c5db199SXin Liclass SmsStore(object): 48*9c5db199SXin Li '''SMS content management - this maintains an internal model of the 49*9c5db199SXin Li index->PDU mapping that the fakemodem program should be returning so 50*9c5db199SXin Li that tests can add and remove individual PDUs and handles generating 51*9c5db199SXin Li the correct set of responses, including the complete SMS list. 52*9c5db199SXin Li ''' 53*9c5db199SXin Li 54*9c5db199SXin Li def __init__(self, fakemodem): 55*9c5db199SXin Li self.fakemodem = fakemodem 56*9c5db199SXin Li self.smsdict = {} 57*9c5db199SXin Li self.fakemodem.SetResponse('\+CMGR=', '', '+CMS ERROR: 321') 58*9c5db199SXin Li self.fakemodem.SetResponse('\+CMGD=', '', '+CMS ERROR: 321') 59*9c5db199SXin Li self._sms_regen_list() 60*9c5db199SXin Li 61*9c5db199SXin Li def sms_insert(self, index, pdu): 62*9c5db199SXin Li '''Add a SMS to the fake modem's list.''' 63*9c5db199SXin Li smsc_len = int(pdu[0:1], 16) 64*9c5db199SXin Li mlen = len(pdu)/2 - smsc_len - 1 65*9c5db199SXin Li 66*9c5db199SXin Li self.fakemodem.RemoveResponse('\+CMGD=') 67*9c5db199SXin Li self.fakemodem.RemoveResponse('\+CMGR=') 68*9c5db199SXin Li self.fakemodem.SetResponse('\+CMGD=%d' % (index), '', '') 69*9c5db199SXin Li self.fakemodem.SetResponse('\+CMGR=%d' % (index), 70*9c5db199SXin Li '+CMGR: 1,,%d\r\n%s' % (mlen, pdu), '') 71*9c5db199SXin Li self.fakemodem.SetResponse('\+CMGR=', '', '+CMS ERROR: 321') 72*9c5db199SXin Li self.fakemodem.SetResponse('\+CMGD=', '', '+CMS ERROR: 321') 73*9c5db199SXin Li 74*9c5db199SXin Li self.smsdict[index] = pdu 75*9c5db199SXin Li self._sms_regen_list() 76*9c5db199SXin Li 77*9c5db199SXin Li def sms_receive(self, index, pdu): 78*9c5db199SXin Li '''Add a SMS to the fake modem's list, like sms_insert(), and generate 79*9c5db199SXin Li an unsolicited new-sms message.''' 80*9c5db199SXin Li self.sms_insert(index, pdu) 81*9c5db199SXin Li self.fakemodem.SendUnsolicited('+CMTI: "ME",%d'%(index)) 82*9c5db199SXin Li 83*9c5db199SXin Li def sms_remove(self, index): 84*9c5db199SXin Li '''Remove a SMS from the fake modem's list''' 85*9c5db199SXin Li self.fakemodem.RemoveResponse('\+CMGR=%d' % (index)) 86*9c5db199SXin Li self.fakemodem.RemoveResponse('\+CMGD=%d' % (index)) 87*9c5db199SXin Li del self.smsdict[index] 88*9c5db199SXin Li self._sms_regen_list() 89*9c5db199SXin Li 90*9c5db199SXin Li def _sms_regen_list(self): 91*9c5db199SXin Li response = '' 92*9c5db199SXin Li keys = list(self.smsdict.keys()) 93*9c5db199SXin Li keys.sort() 94*9c5db199SXin Li for i in keys: 95*9c5db199SXin Li pdu = self.smsdict[i] 96*9c5db199SXin Li smsc_len = int(pdu[0:1],16) 97*9c5db199SXin Li mlen = len(pdu)/2 - smsc_len - 1 98*9c5db199SXin Li response = response + '+CMGL: %d,1,,%d\r\n%s\r\n' % (i, mlen, pdu) 99*9c5db199SXin Li self.fakemodem.SetResponse('\+CMGL=4', response, '') 100*9c5db199SXin Li 101*9c5db199SXin Li 102*9c5db199SXin Liclass SmsTest(object): 103*9c5db199SXin Li def __init__(self, gsmsms): 104*9c5db199SXin Li self.gsmsms = gsmsms 105*9c5db199SXin Li 106*9c5db199SXin Li def compare(self, expected, got): 107*9c5db199SXin Li '''Compare two SMS dictionaries, discounting the index number if 108*9c5db199SXin Li not specified in the first.''' 109*9c5db199SXin Li if expected == got: 110*9c5db199SXin Li return True 111*9c5db199SXin Li if 'index' in expected: 112*9c5db199SXin Li return False 113*9c5db199SXin Li if 'index' not in got: 114*9c5db199SXin Li return False 115*9c5db199SXin Li got = dict(got) 116*9c5db199SXin Li del got['index'] 117*9c5db199SXin Li return expected == got 118*9c5db199SXin Li 119*9c5db199SXin Li def compare_list(self, expected_list, got_list): 120*9c5db199SXin Li if len(expected_list) != len(got_list): 121*9c5db199SXin Li return False 122*9c5db199SXin Li # There must be a more Pythonic way to do this 123*9c5db199SXin Li for (expected,got) in zip(expected_list, got_list): 124*9c5db199SXin Li if self.compare(expected, got) == False: 125*9c5db199SXin Li return False 126*9c5db199SXin Li return True 127*9c5db199SXin Li 128*9c5db199SXin Li def test_get(self, index, expected): 129*9c5db199SXin Li try: 130*9c5db199SXin Li sms = self.gsmsms.Get(index) 131*9c5db199SXin Li except dbus.DBusException as db: 132*9c5db199SXin Li if expected is not None: 133*9c5db199SXin Li raise 134*9c5db199SXin Li return 135*9c5db199SXin Li 136*9c5db199SXin Li if expected is None: 137*9c5db199SXin Li logging.info('Got %s' % sms) 138*9c5db199SXin Li raise error.TestFail('SMS.Get(%d) succeeded unexpectedly' % 139*9c5db199SXin Li index) 140*9c5db199SXin Li if self.compare(expected, sms) == False: 141*9c5db199SXin Li logging.info('Got %s, expected %s' % (sms, expected)) 142*9c5db199SXin Li raise error.TestFail('SMS.Get(%d) did not match expected values' % 143*9c5db199SXin Li index) 144*9c5db199SXin Li 145*9c5db199SXin Li def test_delete(self, index, expected_success): 146*9c5db199SXin Li try: 147*9c5db199SXin Li self.gsmsms.Delete(index) 148*9c5db199SXin Li if expected_success == False: 149*9c5db199SXin Li raise error.TestFail('SMS.Delete(%d) succeeded unexpectedly' % 150*9c5db199SXin Li index) 151*9c5db199SXin Li except dbus.DBusException as db: 152*9c5db199SXin Li if expected_success: 153*9c5db199SXin Li raise 154*9c5db199SXin Li 155*9c5db199SXin Li def test_list(self, expected_list): 156*9c5db199SXin Li sms_list = self.gsmsms.List() 157*9c5db199SXin Li if self.compare_list(expected_list, sms_list) == False: 158*9c5db199SXin Li logging.info('Got %s, expected %s' % (sms_list, expected_list)) 159*9c5db199SXin Li raise error.TestFail('SMS.List() did not match expected values') 160*9c5db199SXin Li 161*9c5db199SXin Li def test_has_none(self): 162*9c5db199SXin Li '''Test that the SMS interface has no messages.''' 163*9c5db199SXin Li self.test_list([]) 164*9c5db199SXin Li self.test_get(1, None) 165*9c5db199SXin Li self.test_delete(1, False) 166*9c5db199SXin Li self.test_delete(2, False) 167*9c5db199SXin Li 168*9c5db199SXin Li def test_has_one(self, parsed_sms): 169*9c5db199SXin Li '''Test that the SMS interface has exactly one message at index 1 170*9c5db199SXin Li As a side effect, deletes the message.''' 171*9c5db199SXin Li self.test_list([parsed_sms]) 172*9c5db199SXin Li self.test_get(1, parsed_sms) 173*9c5db199SXin Li self.test_get(2, None) 174*9c5db199SXin Li self.test_delete(2, False) 175*9c5db199SXin Li self.test_delete(1, True) 176