1*9c5db199SXin Li 2*9c5db199SXin Li# Lint as: python2, python3 3*9c5db199SXin Li# Copyright (c) 2013 The Chromium OS Authors. All rights reserved. 4*9c5db199SXin Li# Use of this source code is governed by a BSD-style license that can be 5*9c5db199SXin Li# found in the LICENSE file. 6*9c5db199SXin Li 7*9c5db199SXin Lifrom __future__ import absolute_import 8*9c5db199SXin Lifrom __future__ import division 9*9c5db199SXin Lifrom __future__ import print_function 10*9c5db199SXin Li 11*9c5db199SXin Liimport cmd 12*9c5db199SXin Liimport dbus 13*9c5db199SXin Liimport dbus.types 14*9c5db199SXin Liimport dbus.exceptions 15*9c5db199SXin Li 16*9c5db199SXin Liimport six 17*9c5db199SXin Li 18*9c5db199SXin Lifrom six.moves import input 19*9c5db199SXin Li 20*9c5db199SXin Liimport common 21*9c5db199SXin Li 22*9c5db199SXin Lifrom autotest_lib.client.cros.cellular.pseudomodem import pm_constants 23*9c5db199SXin Li 24*9c5db199SXin Lifrom autotest_lib.client.cros.cellular import mm1_constants 25*9c5db199SXin Li 26*9c5db199SXin Liclass PseudoModemClient(cmd.Cmd): 27*9c5db199SXin Li """ 28*9c5db199SXin Li Interactive client for PseudoModemManager. 29*9c5db199SXin Li 30*9c5db199SXin Li """ 31*9c5db199SXin Li def __init__(self): 32*9c5db199SXin Li cmd.Cmd.__init__(self) 33*9c5db199SXin Li self.prompt = '> ' 34*9c5db199SXin Li self._bus = dbus.SystemBus() 35*9c5db199SXin Li 36*9c5db199SXin Li 37*9c5db199SXin Li def _get_proxy(self, path=pm_constants.TESTING_PATH): 38*9c5db199SXin Li return self._bus.get_object(mm1_constants.I_MODEM_MANAGER, path) 39*9c5db199SXin Li 40*9c5db199SXin Li 41*9c5db199SXin Li def _get_ism_proxy(self, state_machine): 42*9c5db199SXin Li return self._get_proxy('/'.join([pm_constants.TESTING_PATH, 43*9c5db199SXin Li state_machine])) 44*9c5db199SXin Li 45*9c5db199SXin Li 46*9c5db199SXin Li def Begin(self): 47*9c5db199SXin Li """ 48*9c5db199SXin Li Starts the interactive shell. 49*9c5db199SXin Li 50*9c5db199SXin Li """ 51*9c5db199SXin Li print('\nWelcome to the PseudoModemManager shell!\n') 52*9c5db199SXin Li self.cmdloop() 53*9c5db199SXin Li 54*9c5db199SXin Li 55*9c5db199SXin Li def can_exit(self): 56*9c5db199SXin Li """Override""" 57*9c5db199SXin Li return True 58*9c5db199SXin Li 59*9c5db199SXin Li 60*9c5db199SXin Li def do_is_alive(self, args): 61*9c5db199SXin Li """ 62*9c5db199SXin Li Handles the 'is_alive' command. 63*9c5db199SXin Li 64*9c5db199SXin Li @params args: ignored. 65*9c5db199SXin Li 66*9c5db199SXin Li """ 67*9c5db199SXin Li if args: 68*9c5db199SXin Li print('\nCommand "is_alive" expects no arguments.\n') 69*9c5db199SXin Li return 70*9c5db199SXin Li print(self._get_proxy().IsAlive(dbus_interface=pm_constants.I_TESTING)) 71*9c5db199SXin Li 72*9c5db199SXin Li 73*9c5db199SXin Li def help_is_alive(self): 74*9c5db199SXin Li """ Handles the 'help is_alive' command. """ 75*9c5db199SXin Li print('\nChecks that pseudomodem child process is alive.\n') 76*9c5db199SXin Li 77*9c5db199SXin Li 78*9c5db199SXin Li def do_properties(self, args): 79*9c5db199SXin Li """ 80*9c5db199SXin Li Handles the 'properties' command. 81*9c5db199SXin Li 82*9c5db199SXin Li @param args: Arguments to the command. Unused. 83*9c5db199SXin Li 84*9c5db199SXin Li """ 85*9c5db199SXin Li if args: 86*9c5db199SXin Li print('\nCommand "properties" expects no arguments.\n') 87*9c5db199SXin Li return 88*9c5db199SXin Li try: 89*9c5db199SXin Li props = self._get_proxy().GetAll( 90*9c5db199SXin Li pm_constants.I_TESTING, 91*9c5db199SXin Li dbus_interface=mm1_constants.I_PROPERTIES) 92*9c5db199SXin Li print('\nProperties: ') 93*9c5db199SXin Li for k, v in six.iteritems(props): 94*9c5db199SXin Li print(' ' + k + ': ' + str(v)) 95*9c5db199SXin Li print() 96*9c5db199SXin Li except dbus.exceptions.DBusException as e: 97*9c5db199SXin Li print(('\nAn error occurred while communicating with ' 98*9c5db199SXin Li 'PseudoModemManager: ' + e.get_dbus_name() + ' - ' + 99*9c5db199SXin Li e.message + '\n')) 100*9c5db199SXin Li return False 101*9c5db199SXin Li 102*9c5db199SXin Li 103*9c5db199SXin Li def help_properties(self): 104*9c5db199SXin Li """Handles the 'help properties' command.""" 105*9c5db199SXin Li print('\nReturns the properties under the testing interface.\n') 106*9c5db199SXin Li 107*9c5db199SXin Li 108*9c5db199SXin Li def do_sms(self, args): 109*9c5db199SXin Li """ 110*9c5db199SXin Li Simulates a received SMS. 111*9c5db199SXin Li 112*9c5db199SXin Li @param args: A string containing the sender and the text message 113*9c5db199SXin Li content, in which everything before the first ' ' character 114*9c5db199SXin Li belongs to the sender and everything else belongs to the 115*9c5db199SXin Li message content. For example "Gandalf You shall not pass!" 116*9c5db199SXin Li will be parsed into: 117*9c5db199SXin Li 118*9c5db199SXin Li sender="Gandalf" 119*9c5db199SXin Li content="You shall not pass!" 120*9c5db199SXin Li 121*9c5db199SXin Li Pseudomodem doesn't distinguish between phone numbers and 122*9c5db199SXin Li strings containing non-numeric characters for the sender field 123*9c5db199SXin Li so args can contain pretty much anything. 124*9c5db199SXin Li 125*9c5db199SXin Li """ 126*9c5db199SXin Li arglist = args.split(' ', 1) 127*9c5db199SXin Li if len(arglist) != 2: 128*9c5db199SXin Li print('\nMalformed SMS args: ' + args + '\n') 129*9c5db199SXin Li return 130*9c5db199SXin Li try: 131*9c5db199SXin Li self._get_proxy().ReceiveSms( 132*9c5db199SXin Li arglist[0], arglist[1], 133*9c5db199SXin Li dbus_interface=pm_constants.I_TESTING) 134*9c5db199SXin Li print('\nSMS sent!\n') 135*9c5db199SXin Li except dbus.exceptions.DBusException as e: 136*9c5db199SXin Li print(('\nAn error occurred while communicating with ' 137*9c5db199SXin Li 'PseudoModemManager: ' + e.get_dbus_name() + ' - ' + 138*9c5db199SXin Li e.message + '\n')) 139*9c5db199SXin Li return False 140*9c5db199SXin Li 141*9c5db199SXin Li 142*9c5db199SXin Li def help_sms(self): 143*9c5db199SXin Li """Handles the 'help sms' command.""" 144*9c5db199SXin Li print('\nUsage: sms <sender phone #> <message text>\n') 145*9c5db199SXin Li 146*9c5db199SXin Li 147*9c5db199SXin Li def do_set(self, args): 148*9c5db199SXin Li """ 149*9c5db199SXin Li Handles various commands that start with 'set'. 150*9c5db199SXin Li 151*9c5db199SXin Li @param args: Defines the set command to be issued and its 152*9c5db199SXin Li arguments. Currently supported commands are: 153*9c5db199SXin Li 154*9c5db199SXin Li set pco <pco-value> 155*9c5db199SXin Li 156*9c5db199SXin Li """ 157*9c5db199SXin Li arglist = args.split(' ') 158*9c5db199SXin Li if len(arglist) < 1: 159*9c5db199SXin Li print('\nInvalid command: set ' + args + '\n') 160*9c5db199SXin Li return 161*9c5db199SXin Li if arglist[0] == 'pco': 162*9c5db199SXin Li if len(arglist) == 1: 163*9c5db199SXin Li arglist.append('') 164*9c5db199SXin Li elif len(arglist) != 2: 165*9c5db199SXin Li print('\nExpected: pco <pco-value>. Found: ' + args + '\n') 166*9c5db199SXin Li return 167*9c5db199SXin Li pco_value = arglist[1] 168*9c5db199SXin Li try: 169*9c5db199SXin Li pco_list = [dbus.types.Struct( 170*9c5db199SXin Li [dbus.types.UInt32(1), 171*9c5db199SXin Li dbus.types.Boolean(True), 172*9c5db199SXin Li dbus.types.ByteArray(pco_value)], 173*9c5db199SXin Li signature='ubay')] 174*9c5db199SXin Li self._get_proxy().UpdatePco( 175*9c5db199SXin Li pco_list, dbus_interface=pm_constants.I_TESTING) 176*9c5db199SXin Li print('\nPCO value updated!\n') 177*9c5db199SXin Li except dbus.exceptions.DBusException as e: 178*9c5db199SXin Li print(('\nAn error occurred while communicating with ' 179*9c5db199SXin Li 'PseudoModemManager: ' + e.get_dbus_name() + ' - ' + 180*9c5db199SXin Li e.message + '\n')) 181*9c5db199SXin Li else: 182*9c5db199SXin Li print('\nUnknown command: set ' + args + '\n') 183*9c5db199SXin Li return False 184*9c5db199SXin Li 185*9c5db199SXin Li 186*9c5db199SXin Li def help_set(self): 187*9c5db199SXin Li """Handles the 'help set' command.""" 188*9c5db199SXin Li print ('\nUsage: set pco <pco-value>\n<pco-value> can be empty to set' 189*9c5db199SXin Li ' the PCO value to an empty list.\n') 190*9c5db199SXin Li 191*9c5db199SXin Li 192*9c5db199SXin Li def _get_state_machine(self, args): 193*9c5db199SXin Li arglist = args.split() 194*9c5db199SXin Li if len(arglist) != 1: 195*9c5db199SXin Li print('\nExpected one argument: Name of state machine\n') 196*9c5db199SXin Li return None 197*9c5db199SXin Li try: 198*9c5db199SXin Li return self._get_ism_proxy(arglist[0]) 199*9c5db199SXin Li except dbus.exceptions.DBusException as e: 200*9c5db199SXin Li print('\nNo such interactive state machine.\n') 201*9c5db199SXin Li print('Error obtained: |%s|\n' % repr(e)) 202*9c5db199SXin Li return None 203*9c5db199SXin Li 204*9c5db199SXin Li 205*9c5db199SXin Li def do_is_waiting(self, machine): 206*9c5db199SXin Li """ 207*9c5db199SXin Li Determine if a machine is waiting for an advance call. 208*9c5db199SXin Li 209*9c5db199SXin Li @param machine: Case sensitive name of the machine. 210*9c5db199SXin Li @return: True if |machine| is waiting to be advanced by the user. 211*9c5db199SXin Li 212*9c5db199SXin Li """ 213*9c5db199SXin Li ism = self._get_state_machine(machine) 214*9c5db199SXin Li if not ism: 215*9c5db199SXin Li return False 216*9c5db199SXin Li 217*9c5db199SXin Li try: 218*9c5db199SXin Li is_waiting = ism.IsWaiting( 219*9c5db199SXin Li dbus_interface=pm_constants.I_TESTING_ISM) 220*9c5db199SXin Li print(('\nState machine is %swaiting.\n' % 221*9c5db199SXin Li ('' if is_waiting else 'not '))) 222*9c5db199SXin Li except dbus.exceptions.DBusException as e: 223*9c5db199SXin Li print(('\nCould not determine if |%s| is waiting: |%s|\n' % 224*9c5db199SXin Li (machine, repr(e)))) 225*9c5db199SXin Li return False 226*9c5db199SXin Li 227*9c5db199SXin Li 228*9c5db199SXin Li def help_is_waiting(self): 229*9c5db199SXin Li """Handles the 'help is_waiting' command""" 230*9c5db199SXin Li print ('\nUsage: is_waiting <state-machine-name>\n' 231*9c5db199SXin Li 'Check whether a state machine is waiting for user action. The ' 232*9c5db199SXin Li 'waiting machine can be advanced using the |advance| command.\n' 233*9c5db199SXin Li 'state-machine-name is the case sensitive name of the machine' 234*9c5db199SXin Li 'whose status is to be queried.\n') 235*9c5db199SXin Li 236*9c5db199SXin Li 237*9c5db199SXin Li def do_advance(self, machine): 238*9c5db199SXin Li """ 239*9c5db199SXin Li Advance the given state machine. 240*9c5db199SXin Li 241*9c5db199SXin Li @param machine: Case sensitive name of the state machine to advance. 242*9c5db199SXin Li @returns: True if |machine| was successfully advanced, False otherwise. 243*9c5db199SXin Li 244*9c5db199SXin Li """ 245*9c5db199SXin Li ism = self._get_state_machine(machine) 246*9c5db199SXin Li if not ism: 247*9c5db199SXin Li return False 248*9c5db199SXin Li 249*9c5db199SXin Li try: 250*9c5db199SXin Li success = ism.Advance(dbus_interface=pm_constants.I_TESTING_ISM) 251*9c5db199SXin Li print(('\nAdvanced!\n' if success else '\nCould not advance.\n')) 252*9c5db199SXin Li except dbus.exceptions.DBusException as e: 253*9c5db199SXin Li print('\nError while advancing state machine: |%s|\n' % repr(e)) 254*9c5db199SXin Li return False 255*9c5db199SXin Li 256*9c5db199SXin Li 257*9c5db199SXin Li def help_advance(self): 258*9c5db199SXin Li """Handles the 'help advance' command""" 259*9c5db199SXin Li print ('\nUsage: advance <state-machine-name>\n' 260*9c5db199SXin Li 'Advance a waiting state machine to the next step.\n' 261*9c5db199SXin Li 'state-machine-name is the case sensitive name of the machine' 262*9c5db199SXin Li 'to advance.\n') 263*9c5db199SXin Li 264*9c5db199SXin Li 265*9c5db199SXin Li def do_exit(self, args): 266*9c5db199SXin Li """ 267*9c5db199SXin Li Handles the 'exit' command. 268*9c5db199SXin Li 269*9c5db199SXin Li @param args: Arguments to the command. Unused. 270*9c5db199SXin Li 271*9c5db199SXin Li """ 272*9c5db199SXin Li if args: 273*9c5db199SXin Li print('\nCommand "exit" expects no arguments.\n') 274*9c5db199SXin Li return 275*9c5db199SXin Li resp = input('Are you sure? (yes/no): ') 276*9c5db199SXin Li if resp == 'yes': 277*9c5db199SXin Li print('\nGoodbye!\n') 278*9c5db199SXin Li return True 279*9c5db199SXin Li if resp != 'no': 280*9c5db199SXin Li print('\nDid not understand: ' + resp + '\n') 281*9c5db199SXin Li return False 282*9c5db199SXin Li 283*9c5db199SXin Li 284*9c5db199SXin Li def help_exit(self): 285*9c5db199SXin Li """Handles the 'help exit' command.""" 286*9c5db199SXin Li print ('\nExits the interpreter. Shuts down the pseudo modem manager ' 287*9c5db199SXin Li 'if the interpreter was launched by running pseudomodem.py') 288*9c5db199SXin Li 289*9c5db199SXin Li 290*9c5db199SXin Li do_EOF = do_exit 291*9c5db199SXin Li help_EOF = help_exit 292*9c5db199SXin Li 293*9c5db199SXin Li 294*9c5db199SXin Lidef main(): 295*9c5db199SXin Li """ main method, run when this module is executed as stand-alone. """ 296*9c5db199SXin Li client = PseudoModemClient() 297*9c5db199SXin Li client.Begin() 298*9c5db199SXin Li 299*9c5db199SXin Li 300*9c5db199SXin Liif __name__ == '__main__': 301*9c5db199SXin Li main() 302