hunk ./kapula 267 + call_id = 0 hunk ./kapula 362 - if "--no-oeventsd" in sys.argv: + if "--no-oeventsd" in sys.argv and "--ringtone" in sys.argv: addfile ./answering-machine hunk ./answering-machine 1 +#!/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/event4", os.O_NONBLOCK | os.O_RDONLY) + fcntl.ioctl(fd, 0x40044590, 1) # EVIOCGRAB + gobject.io_add_watch(fd, gobject.IO_IN, 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("alsactl restore -f /etc/alsa-scenarios/stereoout-maxvolume.state") + os.system("vibrator-start") + os.system("ringtone-start") + os.system("ledctrl --on-time 400 --off-time 200 gta02-aux:red"); + 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("ledctrl --off gta02-aux:red"); + self.prev_status = status + + def cbActivate(self): + dbg("cbActivate") + os.system("vibrator-stop") + os.system("ringtone-stop") + os.system("alsactl restore -f /etc/alsa-scenarios/gsmhandset.state") + os.system("ledctrl --on-time 100 --off-time 1500 gta02-aux:red") + self.gsm_call_iface.Activate(1) + + def cbRelease(self): + dbg("cbRelease") + self.gsm_call_iface.Release(1) + + def cbEventActivity(self, source, condition): + dbg("cbEventActivity") + 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("alsactl restore -f /etc/alsa-scenarios/stereoout-maxvolume.state") + 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() hunk ./answering-machine 74 + fcntl.fcntl(fd, fcntl.F_SETFD, fcntl.FD_CLOEXEC)