#!/usr/bin/python import struct import dbus import dbus.glib import gobject import time import os import fcntl import sys input_event_struct = "@LLHHi" input_event_size = struct.calcsize(input_event_struct) logfile = None def set_status(s): f = open("/tmp/answering-machine.status", "w+") f.write("%s\n" % s) f.close() def dbg(s): if logfile: logfile.write("%s %s\n" % (time.strftime("%Y-%m-%d %H:%M:%S"), s)) logfile.flush() else: print("%s %s" % (time.strftime("%H:%M:%S"), s)) def openlog(): global logfile try: f = os.path.expanduser("~/.answering-machine/log.txt") fp = open(f, "a+") logfile = fp except: dbg("failed to open log") def writepid(): #try: f = os.path.expanduser("~/.answering-machine/pid") fp = open(f, "w+") fp.write(str(os.getpid()) + "\n") fp.close() #except: # dbg("failed to write pid") def formatDict(d): return " ".join(["(%s %s)" % (i, d[i]) for i in d.keys()]) class Main(): def __init__(self, loop): self.loop = loop self.status = "release" self.prev_status = "release" openlog() writepid() #dbg("starting") #os.system("auxledblink-start 100 1500") bus = dbus.SystemBus() gsm_device_obj = bus.get_object("org.freesmartphone.ogsmd", "/org/freesmartphone/GSM/Device") self.gsm_network_iface = dbus.Interface(gsm_device_obj, 'org.freesmartphone.GSM.Network') self.gsm_network_iface.connect_to_signal("Status", self.cbNetworkStatus) self.gsm_call_iface = dbus.Interface(gsm_device_obj, 'org.freesmartphone.GSM.Call') self.gsm_call_iface.connect_to_signal("CallStatus", self.cbCallStatus) self.gsm_device_iface = dbus.Interface(gsm_device_obj, 'org.freesmartphone.GSM.Device') self.gsm_sim_iface = dbus.Interface(gsm_device_obj, 'org.freesmartphone.GSM.SIM') self.gsm_sim_iface.connect_to_signal("IncomingStoredMessage", self.cbIncomingMessage) self.gsm_sim_iface.connect_to_signal("IncomingMessageReceipt", self.cbIncomingMessageReceipt) server_obj = bus.get_object("org.freesmartphone.ogsmd", "/org/freesmartphone/GSM/Server") phone_iface = dbus.Interface(server_obj, 'org.freesmartphone.GSM.Phone') #phone_iface.StartAutoRegister("0000") fd = os.open("/dev/input/aux_button", os.O_NONBLOCK | os.O_RDONLY) fcntl.fcntl(fd, fcntl.F_SETFD, fcntl.FD_CLOEXEC) fcntl.ioctl(fd, 0x40044590, 1) # EVIOCGRAB gobject.io_add_watch(fd, gobject.IO_IN | gobject.IO_ERR | gobject.IO_HUP, self.cbEventActivity) dbus_obj = bus.get_object("org.freedesktop.DBus", "/org/freedesktop/DBus") dbus_iface = dbus.Interface(dbus_obj, "org.freedesktop.DBus") dbus_iface.connect_to_signal("NameOwnerChanged", self.cbNameOwnerChanged) self.cbRequestReply() dbg("startup done") def cbRequestReply(self): dbg("cbRequestReply") self.cbStartAntenna(1) def cbStartAntenna(self, w): dbg("cbStartAntenna") self.gsm_device_iface.SetAntennaPower(True, reply_handler = self.cbAntennaPowerReply, error_handler = self.cbAntennaPowerError) def cbAntennaPowerReply(self): dbg("cbAntennaPowerReply") self.gsm_network_iface.Register(reply_handler = self.cbRegisterReply, error_handler = lambda e: (dbg("cbRegisterError %s" % e), self.loop.quit())) def cbAntennaPowerError(self, e): dbg("cbAntennaPowerError %s" % e) if str(e).find("current status is 'enabling'") >= 0 or str(e).find("current status is 'unknown'") >= 0: time.sleep(10) self.cbStartAntenna(0) else: self.gsm_sim_iface.GetAuthStatus(reply_handler = self.cbAuthStatusReply, error_handler = lambda e: (dbg("cbAuthStatusError %s" % e), self.loop.quit())) def cbAuthStatusReply(self, authstatus): dbg("cbAuthStatusReply %s" % authstatus) if authstatus == "READY": self.cbStartAntenna(0) elif authstatus == "SIM PIN": pin = "0000" if not pin: self.loop.quit() self.gsm_sim_iface.SendAuthCode(pin, reply_handler = self.cbAuthCodeReply, error_handler = lambda e: (dbg("cbAuthCodeError %s" % e), self.loop.quit())) else: self.loop.quit() def cbAuthCodeReply(self): dbg("cbAuthCodeReply") self.cbAuthStatusReply("READY") def cbRegisterReply(self): dbg("cbRegisterReply") def cbNetworkStatus(self, status): dbg("cbNetworkStatus %s" % formatDict(status)) def cbCallStatus(self, id, status, properties): dbg("cbCallStatus %d, %s, %s" % (id, status, formatDict(properties))) self.status = status if status == "incoming": if "peer" in properties and properties["peer"] == "+358942832031": set_status("debug_call_received") self.gsm_call_iface.ReleaseAll() os.system("kapula-debug-call-handler &") else: set_status("call_received") os.system("set-alsa-profile stereoout") os.system("vibrator-start") os.system("ringtone-start") os.system("om-led aux_red 255 timer 400 200") if self.prev_status != self.status: if "peer" in properties: number = properties["peer"] else: number = "secret" os.system("incoming-call-notify %s" % number) if status == "release": os.system("ringtone-stop") os.system("vibrator-stop") os.system("om-led aux_red 0") self.prev_status = status def cbActivate(self): dbg("cbActivate") os.system("vibrator-stop") os.system("ringtone-stop") os.system("set-alsa-profile gsmhandset") os.system("om-led aux_red 255 timer 100 1500") self.gsm_call_iface.Activate(1) def cbRelease(self): dbg("cbRelease") self.gsm_call_iface.Release(1) def cbEventActivity(self, source, condition): if condition == gobject.IO_IN: dbg("cbEventActivity") else: dbg("cbEventActivity %s" % repr(condition)) self.loop.quit() data = os.read(source, 512) events = [ data[i:i+input_event_size] for i in range(0, len(data), input_event_size) ] for e in events: timestamp, microseconds, typ, code, value = struct.unpack( input_event_struct, e ) # We need more then just second accuracy timestamp = timestamp + microseconds/1000000.0 if typ != 0x00: # ignore EV_SYN (synchronization event) dbg("event %s %s %s %s %s" % (self.status, timestamp, typ, code, value)) if code == 169 and value == 1: if self.status == "incoming": self.cbActivate() elif self.status == "active": self.cbRelease() if code == 116 and value == 1: os.system("sudo apm -s") return True def cbIncomingMessage(self, index): dbg("cbIncomingMessage %s" % index) set_status("sms_received") os.system("set-alsa-profile stereoout") os.system("sms-receive-notify") def cbIncomingMessageReceipt(self, *args): dbg("cbIncomingMessageReceipt %s" % repr(args)) set_status("sms_received_receipt") def cbNameOwnerChanged(self, name, oldOwner, newOwner): if name == "org.freesmartphone.ogsmd" and newOwner == "": dbg("cbNameOwnerChanged %s %s %s" % (name, oldOwner, newOwner)) self.loop.quit() if __name__ == "__main__": loop = gobject.MainLoop() Main(loop) loop.run()