From 8ead97831e25f820bd093a6e2717bf63aab17a09 Mon Sep 17 00:00:00 2001 From: Enrico Zini Date: Fri, 26 Mar 2010 15:34:37 +0000 Subject: [PATCH] Try to get info out of GSM --- README | 14 ++ test/test-gsm-receive.vala | 357 +++++++++++++++++++++++++++++++++++++ 2 files changed, 371 insertions(+) diff --git a/README b/README index 0d17b4c..12d0788 100644 --- a/README +++ b/README @@ -176,6 +176,19 @@ TODO list / wish list * FSO API "documentation": http://git.freesmartphone.org/?p=specs.git;a=blob_plain;f=html/index.html;hb=HEAD +using vala-dbus-binding-tool: + + mdbus -s org.freesmartphone.ogsmd /org/freesmartphone/GSM/Device org.freedesktop.DBus.Introspectable.Introspect > /tmp/api.xml + vi /tmp/api.xml + convert to xml: + remove quotes at begin and end + :$s/\n/^M/g + mkdir /tmp/foo + vala-dbus-binding-tool --directory=/tmp/foo --api-path=/tmp/api.xml + + + + * Features to add: - if GPS time is more than 1 minute and less than 1 hour different than the system time, automatically sync it @@ -194,6 +207,7 @@ TODO list / wish list + GSM status on main screen (with messages while coming online, and operator, power and so on) - log incoming messages + (first as a standalone app quick to compile) - log and refuse incoming calls to "move" the GSM device to my laptop: socat FILE:/dev/ttySAC0 TCP-LISTEN:12345,bind=192.168.0.202 diff --git a/test/test-gsm-receive.vala b/test/test-gsm-receive.vala index 7ad3542..b1110f8 100644 --- a/test/test-gsm-receive.vala +++ b/test/test-gsm-receive.vala @@ -22,6 +22,363 @@ using GLib; //string VERSION = "0.1"; +public class GSMReceive: Object, zavai.Resource +{ + public dynamic DBus.Object network; + public dynamic DBus.Object call; + + public GSMReceive() + { + zavai.gsm.gsm.request("GSMReceive"); + + network = zavai.registry.sbus.get_object( + "org.freesmartphone.ogsmd", + "/org/freesmartphone/GSM/Device", + "org.freesmartphone.GSM.Network"); + + call = zavai.registry.sbus.get_object( + "org.freesmartphone.ogsmd", + "/org/freesmartphone/GSM/Device", + "org.freesmartphone.GSM.Call"); + + network.Status += on_network_Status; + network.SignalStrength += on_network_SignalStrength; + call.CallStatus += on_call_Status; + } + + public void shutdown() + { + zavai.gsm.gsm.release("GSMReceive"); + } + + public void on_network_SignalStrength(int strength) + { + stderr.printf("SIGNAL STRENGTH %d\n", strength); + } + + public void on_network_Status(GLib.HashTable status) + { + stderr.printf("NETWORK STATUS\n"); + + // dbg("cbNetworkStatus %s" % formatDict(status)) + } + + public void on_call_Status(int index, string status, GLib.HashTable properties) + { + stderr.printf("CALL STATUS %d %s\n", index, status); + /* + dbg("cbCallStatus %d, %s, %s" % (id, status, formatDict(properties))) + self.status = status + if status == "incoming": + if "peer" in properties and properties["peer"] == "+358942832031": + self.gsm_call_iface.ReleaseAll() + os.system("kapula-debug-call-handler &") + else: + 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 status == "release": + os.system("ringtone-stop") + os.system("vibrator-stop") + os.system("ledctrl --off gta02-aux:red"); + */ + } + + +/* + def onIncomingUssd( self, mode, message ): + logger.info( "USSD Message: %s" % message ) + self.main.groups["alert"].activate( "Operator Message%s" % message, [("OK")] ) + def onCallStatus( self, id, status, properties ): + self.call = id + self.update_status(status) + if not status in ["release"]: + if "peer" in properties: + self.part_text_set( "label", self.main.groups["contacts"].tryNumberToName( properties[ "peer" ] ) ) + self.part_text_set( "sublabel", properties[ "peer" ] ) + else: + self.part_text_set( "label", _("unknown number") ) + self.part_text_set( "sublabel", "" ) + + @edje.decorators.signal_callback( "mouse,clicked,1", "button_*" ) + def on_edje_signal_dialer_button_pressed(self, emission, source): + key = source.split("_", 1)[1] + if key in ("0", "1", "2", "3", "4", "5", "6", "7", "8", "9"): + dbus_object.gsm_call_iface.SendDtmf( key ) + self.text.append(key) + elif key in "star": + dbus_object.gsm_call_iface.SendDtmf( "*" ) + self.text.append("*") + elif key in "hash": + dbus_object.gsm_call_iface.SendDtmf( "#" ) + self.text += "#" + # The trailing whitespace is a workaround for the one char invisible + # bug due to some problems with scaling of text parts. + self.part_text_set("label", "".join(self.text)+" ") + + @edje.decorators.signal_callback("call_button_pressed", "button_right") + def on_edje_signal_call_button_right_pressed(self, emission, source): + self.main.transition_to("call") + + def sendMessage( self, index ): + logger.info( "trying to send message w/ index %d..." % index ) + dbus_object.gsm_sim_iface.SendStoredMessage( index, reply_handler=self.cbSendReply, error_handler=self.cbSendError ) + + def cbSendReply( self, reference, timestamp ): + logger.info( "sent message successfully w/ reference number %d (timestamp: %s)" % ( reference, timestamp ) ) + + def cbSendError( self, e ): + logger.error( "could not send message. leaving in outgoing. error was: %s" % e ) + + def cbStoreReply( self, result ): + logger.info( "stored message lives at SIM position %d" % result ) + self.sendMessage( result ) + if not self.busy: + dbus_object.gsm_sim_iface.RetrieveMessagebook( + "all", + reply_handler=self.cbMessagebookReply, + error_handler=self.cbMessagebookError + ) + self.busy = True + + def cbStoreError( self, e ): + logger.warning( "error while storing message - %s" % e.get_dbus_name() ) + if e.get_dbus_name() == "org.freesmartphone.GSM.SIM.MemoryFull": + self.main.groups["alert"].activate( "Failed to send messageSIM Memory Full", [("OK")] ) + + def cbSend1( self, selected, cb_data ): + self.main.groups["text_edit"].setup( + "sms", + "", # text + selected[0], # title + selected[1], # reference + self.cbSend2 + ) + + def cbSend2( self, text, number ): + if dbus_object.gsm_device_obj: + dbus_object.gsm_sim_iface.StoreMessage( + number, text, {}, + reply_handler=self.cbStoreReply, + error_handler=self.cbStoreError + ) + + def cbDelete( self, result, reference ): + if result == "abort": + return + if dbus_object.gsm_device_obj: + dbus_object.gsm_sim_iface.DeleteMessage( + reference + ) + for i in range( len( self.messagebook ) ): + if self.messagebook[i][0] == reference: + del self.messagebook[i] + break + self.updateList() + + def cbForward( self, selected, text ): + if dbus_object.gsm_device_obj: + dbus_object.gsm_sim_iface.StoreMessage( + selected[1], text, {}, + reply_handler=self.cbStoreReply, + error_handler=self.cbStoreError + ) + + def cbReply( self, text, number): + if dbus_object.gsm_device_obj: + dbus_object.gsm_sim_iface.StoreMessage( + number, text, {}, + reply_handler=self.cbStoreReply, + error_handler=self.cbStoreError + ) + + def cbMenu( self, result ): + if result == _("send"): + self.main.groups["contacts"].prepare() + if self.main.groups["contacts"].ready: + self.main.groups["list_choose"].setup( + "sms", + [ (x[1], x[2]) for x in self.main.groups["contacts"].phonebook], + None, + self.cbSend1 + ) + elif result == _("delete"): + self.main.groups["alert"].activate( + _("delete?"), + (_("abort"), _("delete")), + self.current[self.selected][0], # reference + self.cbDelete + ) + elif result == _("forward"): + self.main.groups["contacts"].prepare() + if self.main.groups["contacts"].ready: + self.main.groups["list_choose"].setup( + "sms", + [ (x[1], x[2] ) for x in self.main.groups["contacts"].phonebook], + self.current[self.selected][3], + self.cbForward + ) + elif result == _("reply"): + self.main.groups["text_edit"].setup( + "sms", + "", # text + self.current[self.selected][2], # title = number + self.current[self.selected][2], # reference = number + self.cbReply + ) + + def cbMessagebookReply( self, result ): + logger.info( "retrieved messagebook: %s" % result ) + self.busy = False + self.messagebook = result + self.ready = True + self.updateList() + self.main.groups["main"].targets["sms"] = True + self.main.groups["main"].update() + if not self.newindex is None: + message = [x for x in self.messagebook if x[0] == self.newindex] + self.newindex = None + if message and self.main.current_group == self.main.groups["main"]: + message = message[0] + if "read" in message[1]: + from_to = _("From") + timestamp = message[4]["timestamp"] + else: + from_to = _("To") + timestamp = _("Unknown") + from_text = self.main.groups["contacts"].tryNumberToName( message[2] ) + self.main.groups["text_show"].setup( + "sms", + _("%s: %s
Date: %s

%s") % ( + from_to, + from_text, + timestamp, + textblock_escape( message[3] ).replace( '\n', '
' ) + ) + ) + if dbus_object.gsm_device_obj: + messagebookInfo = dbus_object.gsm_sim_iface.GetMessagebookInfo() + if messagebookInfo["used"] == messagebookInfo["last"]: + self.main.groups["alert"].activate( "WarningSIM Memory Full", [("OK")] ) + + def cbMessagebookError( self, e ): + logger.warning( "error while retrieving messagebook" ) + self.busy = False + + def onIncomingMessage( self, index ): + logger.info( "new message! Retrieving messagebook..." ) + self.newindex = index + if not self.busy: + dbus_object.gsm_sim_iface.RetrieveMessagebook( + "all", + reply_handler=self.cbMessagebookReply, + error_handler=self.cbMessagebookError + ) + self.busy = True + + def prepare( self ): + if not self.ready and not self.busy: + if dbus_object.gsm_device_obj: + logger.info( "retrieving messagebook..." ) + dbus_object.gsm_sim_iface.RetrieveMessagebook( + "all", + reply_handler=self.cbMessagebookReply, + error_handler=self.cbMessagebookError + ) + self.busy = True + else: + # Fake messagebook... + self.cbMessagebookReply( [ + (0, "read", "+4544555", "Hello World!"), + (1, "read", "+456663443", "Zhone!"), + (2, "read", "+456663443", "Hi Guy\nGuess what, I now "+ + "know to write multi-line SMSs.\nIsn't that "+ + "nice?\n\nSome Buddy"), + (3, "read", "Flash SMS", "An SMS without digits. Strange, isn't it?"), + ] ) + + def onReadyStatus( self, status ): + logger.debug( "SIM is ready: %s" % status ) + if status: + # Force update + self.ready = False + self.prepare() + + def onShow( self ): + self.prepare() + self.updateList() + + def updateList( self): + self.main.groups["contacts"].prepare() + self.pages = max( ( len( self.messagebook ) - 1 ) / 6 + 1, 1 ) + if self.page >= self.pages: + self.page = self.pages - 1 + if self.page < 0: + self.page = 0 + self.current = self.messagebook[self.page*6:(self.page+1)*6] + text = u"".join( [u"□"]*self.page+[u"▣"]+[u"□"]*(self.pages-self.page-1) ) + self.part_text_set( "pager", text ) + for i in range( 0, len( self.current ) ): + main_text = self.main.groups["contacts"].tryNumberToName( self.current[i][2] ) + self.part_text_set( "label_main_list_%i" % i, main_text ) + sub_text = " ".join(self.current[i][3].splitlines()) + self.part_text_set( "label_sub_list_%i" % i, u"(%s) %s" % ( self.current[i][1], sub_text ) ) + for i in range( len( self.current ), 6): + self.part_text_set( "label_main_list_%i" % i, u"" ) + self.part_text_set( "label_sub_list_%i" % i, u"" ) + self.selected = None + for i in range( 6 ): + self.signal_emit( "deactivate_target_list_%i" % i, "" ) + + + @edje.decorators.signal_callback( "mouse,clicked,1", "target_list_*" ) + def on_edje_signal_button_list_pressed( self, emission, source ): + id = int( source.split( "_" )[-1] ) + if self.selected == id: + return + if self.selected is not None: + self.signal_emit( "deactivate_target_list_%i" % self.selected, "" ) + self.signal_emit( "activate_target_list_%i" % id, "" ) + self.selected = id + + @edje.decorators.signal_callback( "mouse,clicked,1", "button_action_left" ) + def on_edje_signal_button_action_left_pressed( self, emission, source ): + self.page -= 1 + self.updateList() + + @edje.decorators.signal_callback( "mouse,clicked,1", "button_action_right" ) + def on_edje_signal_button_action_right_pressed( self, emission, source ): + self.page += 1 + self.updateList() + + @edje.decorators.signal_callback( "mouse,clicked,1", "button_action_open" ) + def on_edje_signal_button_action_open_pressed( self, emission, source ): + if self.selected is not None: + if "read" in self.current[self.selected][1]: + from_to = _("From") + timestamp = self.current[self.selected][4]["timestamp"] + else: + from_to = _("To") + timestamp = _("Unknown") + from_text = self.main.groups["contacts"].tryNumberToName( self.current[self.selected][2] ) + self.main.groups["text_show"].setup( + "sms", + _("%s: %s
Date: %s

%s") % ( + from_to, + from_text, + timestamp, + textblock_escape( self.current[self.selected][3] ).replace( '\n', '
' ) + ) + ) + + @edje.decorators.signal_callback( "mouse,clicked,1", "button_bottom_middle" ) + def on_edje_signal_button_bottom_middle_pressed( self, emission, source ): + self.main.groups["menu"].activate( ( _("send"), _("delete"), _("forward"), _("reply") ), self.cbMenu ) + self.main.groups["menu"].part_text_set( "target_label_cancel", _("cancel") ) +*/ +} + static int main (string[] args) { Gtk.init (ref args); Gst.init (ref args); -- 2.39.5