#!/usr/bin/python3 from gi.repository import GLib import sys import dbus import dbus.service import dbus.mainloop.glib import signal def handler(signum, frame): raise Exception("\nSingle tone is finished!") class GoBack(dbus.DBusException): _dbus_error_name = "org.ofono.Error.GoBack" class EndSession(dbus.DBusException): _dbus_error_name = "org.ofono.Error.EndSession" class Busy(dbus.DBusException): _dbus_error_name = "org.ofono.Error.Busy" class StkAgent(dbus.service.Object): exit_on_release = True timeout_id = 0 timeout_reply_handler = None def set_exit_on_release(self, exit_on_release): self.exit_on_release = exit_on_release def timeout_callback(self): self.timeout_id = 0 self.timeout_reply_handler() return False def call_added(self, path, properties): print("call added %s" % (path)) if (self.timeout_id > 0): GLib.source_remove(self.timeout_id) self.timeout_callback() @dbus.service.method("org.ofono.SimToolkitAgent", in_signature="", out_signature="") def Release(self): print("Release") if self.exit_on_release: mainloop.quit() @dbus.service.method("org.ofono.SimToolkitAgent", in_signature="sya(sy)n", out_signature="y") def RequestSelection(self, title, icon, items, default): print("Title: (%s)" % (title)) print("Icon: (%d)" % (int(icon))) index = 0 for item in items: print("%d. %s (icon: %d)" % (index, item[0], int(item[1]))) index += 1 print("\nDefault: %d" % (default)) select = input("Enter Selection (t, b):") if select == 'b': raise GoBack("User wishes to go back") elif select == 't': raise EndSession("User wishes to terminate session") else: return int(select) @dbus.service.method("org.ofono.SimToolkitAgent", in_signature="syb", out_signature="", async_callbacks=("reply_func", "error_func")) def DisplayText(self, title, icon, urgent, reply_func, error_func): print("DisplayText (%s)" % (title)) print("Icon: (%d)" % (int(icon))) print("Urgent: (%d)" % (urgent)) key = input("Press return to clear ('t' terminates, " "'b' goes back, 'n' busy, " "'w' return and wait):") if key == 'w': seconds = 60 else: seconds = 0 if key == 'b': raise GoBack("User wishes to go back") elif key == 't': raise EndSession("User wishes to terminate session") elif key == 'n': raise Busy("User wishes to simulate busy screen") if (seconds > 0): print("Waiting for %d seconds" % (seconds)) self.timeout_reply_handler = reply_func self.timeout_id = GLib.timeout_add_seconds(seconds, self.timeout_callback) @dbus.service.method("org.ofono.SimToolkitAgent", in_signature="sysyyb", out_signature="s") def RequestInput(self, title, icon, default, min_chars, max_chars, hide_typing): print("Title: (%s)" % (title)) print("Icon: (%d)" % (int(icon))) print("Default: (%s)" % (default)) print("Hide typing: (%s)" % (hide_typing)) print("Enter characters, min: %d, max: %d:" % (min_chars, max_chars)) userin = input("") return userin @dbus.service.method("org.ofono.SimToolkitAgent", in_signature="sysyyb", out_signature="s") def RequestDigits(self, title, icon, default, min_chars, max_chars, hide_typing): print("Title: (%s)" % (title)) print("Icon: (%d)" % (int(icon))) print("Default: (%s)" % (default)) print("Hide typing: (%s)" % (hide_typing)) print("Enter digits, min: %d, max: %d:" % (min_chars, max_chars)) userin = input("'t' terminates, 'b' goes back:") if userin == 'b': raise GoBack("User wishes to go back") elif userin == 't': raise EndSession("User wishes to terminate session") else: return userin @dbus.service.method("org.ofono.SimToolkitAgent", in_signature="sy", out_signature="s") def RequestKey(self, title, icon): print("Title: (%s)" % (title)) print("Icon: (%d)" % (int(icon))) key = input("Enter Key (t, b):") if key == 'b': raise GoBack("User wishes to go back") elif key == 't': raise EndSession("User wishes to terminate session") else: return key @dbus.service.method("org.ofono.SimToolkitAgent", in_signature="sy", out_signature="s") def RequestDigit(self, title, icon): print("Title: (%s)" % (title)) print("Icon: (%d)" % (int(icon))) key = input("Enter Digit (t, b):") if key == 'b': raise GoBack("User wishes to go back") elif key == 't': raise EndSession("User wishes to terminate session") else: return key @dbus.service.method("org.ofono.SimToolkitAgent", in_signature="sy", out_signature="s") def RequestQuickDigit(self, title, icon): print("Title: (%s)" % (title)) print("Icon: (%d)" % (int(icon))) key = input("Quick digit (0-9, *, #, t, b):") if key == 'b': raise GoBack("User wishes to go back") elif key == 't': raise EndSession("User wishes to terminate session") else: return key @dbus.service.method("org.ofono.SimToolkitAgent", in_signature="sy", out_signature="b") def RequestConfirmation(self, title, icon): print("Title: (%s)" % (title)) print("Icon: (%d)" % (int(icon))) key = input("Enter Confirmation (t, b, y, n):") if key == 'b': raise GoBack("User wishes to go back") elif key == 't': raise EndSession("User wishes to terminate session") elif key == 'y': return True else: return False @dbus.service.method("org.ofono.SimToolkitAgent", in_signature="sy", out_signature="b") def ConfirmCallSetup(self, info, icon): print("Information: (%s)" % (info)) print("Icon: (%d)" % (int(icon))) key = input("Enter Confirmation (t, y, n):") if key == 't': raise EndSession("User wishes to terminate session") elif key == 'y': return True else: return False @dbus.service.method("org.ofono.SimToolkitAgent", in_signature="sys", out_signature="b") def ConfirmLaunchBrowser(self, info, icon, url): print("Information: (%s)" % (info)) print("Icon: (%d)" % (int(icon))) print("URL (%s)" % (url)) key = input("Enter Confirmation (y, n):") if key == 'y': return True else: return False @dbus.service.method("org.ofono.SimToolkitAgent", in_signature="", out_signature="") def Cancel(self): print("Cancel") @dbus.service.method("org.ofono.SimToolkitAgent", in_signature="ssy", out_signature="") def PlayTone(self, tone, text, icon): print("PlayTone: %s" % (tone)) print("Text: %s" % (text)) print("Icon: %d" % (int(icon))) signal.signal(signal.SIGALRM, handler) signal.alarm(5) try: key = input("Press return to end before end of" " single tone (t):") signal.alarm(0) if key == 't': raise EndSession("User wishes to terminate" " session") except Exception as exc: print(exc) @dbus.service.method("org.ofono.SimToolkitAgent", in_signature="ssy", out_signature="", async_callbacks=("reply_func", "error_func")) def LoopTone(self, tone, text, icon, reply_func, error_func): print("LoopTone: %s" % (tone)) print("Text: %s" % (text)) print("Icon: %d" % (int(icon))) key = input("Press return to end before timeout " "('t' terminates, 'w' return and wait):") if key == 'w': seconds = 60 else: seconds = 0 if key == 't': raise EndSession("User wishes to terminate session") if (seconds > 0): print("Waiting for %d seconds" % (seconds)) self.timeout_reply_handler = reply_func self.timeout_id = GLib.timeout_add_seconds(seconds, self.timeout_callback) @dbus.service.method("org.ofono.SimToolkitAgent", in_signature="sy", out_signature="") def DisplayActionInformation(self, text, icon): print("Text: %s" % (text)) print("Icon: %d" % (int(icon))) @dbus.service.method("org.ofono.SimToolkitAgent", in_signature="sy", out_signature="") def DisplayAction(self, text, icon): print("Text: (%s)" % (text)) print("Icon: (%d)" % (int(icon))) key = input("Press 't' to terminate the session ") if key == 't': raise EndSession("User wishes to terminate session") @dbus.service.method("org.ofono.SimToolkitAgent", in_signature="sy", out_signature="b") def ConfirmOpenChannel(self, info, icon): print("Open channel confirmation: (%s)" % (info)) print("Icon: (%d)" % (int(icon))) key = input("Enter Confirmation (t, y, n):") if key == 't': raise EndSession("User wishes to terminate session") elif key == 'y': return True else: return False _dbus2py = { dbus.String : str, dbus.UInt32 : int, dbus.Int32 : int, dbus.Int16 : int, dbus.UInt16 : int, dbus.UInt64 : int, dbus.Int64 : int, dbus.Byte : int, dbus.Boolean : bool, dbus.ByteArray : str, dbus.ObjectPath : str } def dbus2py(d): t = type(d) if t in _dbus2py: return _dbus2py[t](d) if t is dbus.Dictionary: return dict([(dbus2py(k), dbus2py(v)) for k, v in d.items()]) if t is dbus.Array and d.signature == "y": return "".join([chr(b) for b in d]) if t is dbus.Array or t is list: return [dbus2py(v) for v in d] if t is dbus.Struct or t is tuple: return tuple([dbus2py(v) for v in d]) return d def pretty(d): d = dbus2py(d) t = type(d) if t in (dict, tuple, list) and len(d) > 0: if t is dict: d = ", ".join(["%s = %s" % (k, pretty(v)) for k, v in d.items()]) return "{ %s }" % d d = " ".join([pretty(e) for e in d]) if t is tuple: return "( %s )" % d if t is str: return "%s" % d return str(d) def property_changed(name, value): print("SimToolKit property: %s changed to '%s'" % (name, pretty(value))) if __name__ == '__main__': if len(sys.argv) == 2: mode = sys.argv[1] else: mode = 'menu' dbus.mainloop.glib.DBusGMainLoop(set_as_default=True) bus = dbus.SystemBus() manager = dbus.Interface(bus.get_object("org.ofono", "/"), "org.ofono.Manager") modems = manager.GetModems() for path, properties in modems: if "org.ofono.SimToolkit" in properties["Interfaces"]: stk = dbus.Interface(bus.get_object('org.ofono', path), 'org.ofono.SimToolkit') if "org.ofono.VoiceCallManager" in properties["Interfaces"]: vcm = dbus.Interface(bus.get_object('org.ofono', path), 'org.ofono.VoiceCallManager') stk.connect_to_signal("PropertyChanged", property_changed) properties = stk.GetProperties() if mode == 'menu': if "MainMenuTitle" in properties: print("Main Menu:") print("%s" % (properties["MainMenuTitle"])) print("\n") if "MainMenu" in properties: print("Items:") index = 0 for item in properties["MainMenu"]: print("%d. %s" % (index, item[0])) index += 1 path = "/test/agent" agent = StkAgent(bus, path) try: vcm.connect_to_signal("CallAdded", agent.call_added) except: pass select = int(input("Enter Selection: ")) stk.SelectItem(select, path) elif mode == 'agent': path = "/test/agent" agent = StkAgent(bus, path) try: vcm.connect_to_signal("CallAdded", agent.call_added) except: pass stk.RegisterAgent(path) print("Default Agent registered - Waiting for STK command...") else: print("%s [menu|agent]" % (sys.argv[0])) exit(0) mainloop = GLib.MainLoop() mainloop.run()