2 * test-gsm-receive - Play with receiving GSM data
4 * Copyright (C) 2010 Enrico Zini <enrico@enricozini.org>
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 public DBus.Connection sbus;
25 //string VERSION = "0.1";
27 public class GSMReceive: Object //, zavai.Resource
29 public dynamic DBus.Object device;
30 public dynamic DBus.Object network;
31 public dynamic DBus.Object sim;
32 public dynamic DBus.Object call;
36 //zavai.gsm.gsm.request("GSMReceive");
38 device = sbus.get_object(
39 "org.freesmartphone.ogsmd",
40 "/org/freesmartphone/GSM/Device",
41 "org.freesmartphone.GSM.Device");
43 network = sbus.get_object(
44 "org.freesmartphone.ogsmd",
45 "/org/freesmartphone/GSM/Device",
46 "org.freesmartphone.GSM.Network");
47 sim = sbus.get_object(
48 "org.freesmartphone.ogsmd",
49 "/org/freesmartphone/GSM/Device",
50 "org.freesmartphone.GSM.SIM");
52 call = sbus.get_object(
53 "org.freesmartphone.ogsmd",
54 "/org/freesmartphone/GSM/Device",
55 "org.freesmartphone.GSM.Call");
57 stderr.printf("Antenna is %s\n", device.GetAntennaPower() ? "on" : "off");
58 stderr.printf("Signal strength: %d\n", network.GetSignalStrength());
59 stderr.printf("Calling identification: %s\n", network.GetCallingIdentification());
60 GLib.HashTable<string, GLib.Value?> status = network.GetStatus();
61 stderr.printf("Network status:\n");
64 network.Status += on_network_Status;
65 network.SignalStrength += on_network_SignalStrength;
66 call.CallStatus += on_call_Status;
67 sim.IncomingStoredMessage += on_sim_IncomingStoredMessage;
70 public void shutdown()
72 //zavai.gsm.gsm.release("GSMReceive");
75 protected void dump_table(HashTable<string, Value?> vals)
77 vals.for_each((pk, pv) => {
78 string k = (string)pk;
79 Value? v = (Value?)pv;
80 stderr.printf("K: %s V: %s\n", k, v == null ? "(null)" : v.strdup_contents());
84 public void on_sim_IncomingStoredMessage(DBus.Object sender, int index)
86 stderr.printf("INCOMING STORED MESSAGE %d\n", index);
90 public void dump_message(int index)
92 string state, sender, msg;
93 GLib.HashTable<string, GLib.Value?> info;
94 sim.RetrieveMessage(index, out state, out sender, out msg, out info);
95 stderr.printf("state: %s\n", state);
96 stderr.printf("sender: %s\n", sender);
97 stderr.printf("msg: %s\n", msg);
101 public void on_network_SignalStrength(DBus.Object sender, int strength)
103 stderr.printf("SIGNAL STRENGTH %d\n", strength);
106 public void on_network_Status(DBus.Object sender, HashTable<string, Value?> status)
108 stderr.printf("NETWORK STATUS\n");
111 // dbg("cbNetworkStatus %s" % formatDict(status))
114 public void on_call_Status(DBus.Object sender, int index, string status, HashTable<string, Value?> properties)
116 stderr.printf("CALL STATUS %d %s\n", index, status);
117 dump_table(properties);
119 dbg("cbCallStatus %d, %s, %s" % (id, status, formatDict(properties)))
121 if status == "incoming":
122 if "peer" in properties and properties["peer"] == "+358942832031":
123 self.gsm_call_iface.ReleaseAll()
124 os.system("kapula-debug-call-handler &")
126 os.system("alsactl restore -f /etc/alsa-scenarios/stereoout-maxvolume.state")
127 os.system("vibrator-start")
128 os.system("ringtone-start")
129 os.system("ledctrl --on-time 400 --off-time 200 gta02-aux:red");
130 if status == "release":
131 os.system("ringtone-stop")
132 os.system("vibrator-stop")
133 os.system("ledctrl --off gta02-aux:red");
139 def onIncomingUssd( self, mode, message ):
140 logger.info( "USSD Message: %s" % message )
141 self.main.groups["alert"].activate( "<title>Operator Message</title>%s" % message, [("OK")] )
142 def onCallStatus( self, id, status, properties ):
144 self.update_status(status)
145 if not status in ["release"]:
146 if "peer" in properties:
147 self.part_text_set( "label", self.main.groups["contacts"].tryNumberToName( properties[ "peer" ] ) )
148 self.part_text_set( "sublabel", properties[ "peer" ] )
150 self.part_text_set( "label", _("unknown number") )
151 self.part_text_set( "sublabel", "" )
153 @edje.decorators.signal_callback( "mouse,clicked,1", "button_*" )
154 def on_edje_signal_dialer_button_pressed(self, emission, source):
155 key = source.split("_", 1)[1]
156 if key in ("0", "1", "2", "3", "4", "5", "6", "7", "8", "9"):
157 dbus_object.gsm_call_iface.SendDtmf( key )
158 self.text.append(key)
160 dbus_object.gsm_call_iface.SendDtmf( "*" )
161 self.text.append("*")
163 dbus_object.gsm_call_iface.SendDtmf( "#" )
165 # The trailing whitespace is a workaround for the one char invisible
166 # bug due to some problems with scaling of text parts.
167 self.part_text_set("label", "".join(self.text)+" ")
169 @edje.decorators.signal_callback("call_button_pressed", "button_right")
170 def on_edje_signal_call_button_right_pressed(self, emission, source):
171 self.main.transition_to("call")
173 def sendMessage( self, index ):
174 logger.info( "trying to send message w/ index %d..." % index )
175 dbus_object.gsm_sim_iface.SendStoredMessage( index, reply_handler=self.cbSendReply, error_handler=self.cbSendError )
177 def cbSendReply( self, reference, timestamp ):
178 logger.info( "sent message successfully w/ reference number %d (timestamp: %s)" % ( reference, timestamp ) )
180 def cbSendError( self, e ):
181 logger.error( "could not send message. leaving in outgoing. error was: %s" % e )
183 def cbStoreReply( self, result ):
184 logger.info( "stored message lives at SIM position %d" % result )
185 self.sendMessage( result )
187 dbus_object.gsm_sim_iface.RetrieveMessagebook(
189 reply_handler=self.cbMessagebookReply,
190 error_handler=self.cbMessagebookError
194 def cbStoreError( self, e ):
195 logger.warning( "error while storing message - %s" % e.get_dbus_name() )
196 if e.get_dbus_name() == "org.freesmartphone.GSM.SIM.MemoryFull":
197 self.main.groups["alert"].activate( "<title>Failed to send message</title>SIM Memory Full", [("OK")] )
199 def cbSend1( self, selected, cb_data ):
200 self.main.groups["text_edit"].setup(
204 selected[1], # reference
208 def cbSend2( self, text, number ):
209 if dbus_object.gsm_device_obj:
210 dbus_object.gsm_sim_iface.StoreMessage(
212 reply_handler=self.cbStoreReply,
213 error_handler=self.cbStoreError
216 def cbDelete( self, result, reference ):
217 if result == "abort":
219 if dbus_object.gsm_device_obj:
220 dbus_object.gsm_sim_iface.DeleteMessage(
223 for i in range( len( self.messagebook ) ):
224 if self.messagebook[i][0] == reference:
225 del self.messagebook[i]
229 def cbForward( self, selected, text ):
230 if dbus_object.gsm_device_obj:
231 dbus_object.gsm_sim_iface.StoreMessage(
232 selected[1], text, {},
233 reply_handler=self.cbStoreReply,
234 error_handler=self.cbStoreError
237 def cbReply( self, text, number):
238 if dbus_object.gsm_device_obj:
239 dbus_object.gsm_sim_iface.StoreMessage(
241 reply_handler=self.cbStoreReply,
242 error_handler=self.cbStoreError
245 def cbMenu( self, result ):
246 if result == _("send"):
247 self.main.groups["contacts"].prepare()
248 if self.main.groups["contacts"].ready:
249 self.main.groups["list_choose"].setup(
251 [ (x[1], x[2]) for x in self.main.groups["contacts"].phonebook],
255 elif result == _("delete"):
256 self.main.groups["alert"].activate(
258 (_("abort"), _("delete")),
259 self.current[self.selected][0], # reference
262 elif result == _("forward"):
263 self.main.groups["contacts"].prepare()
264 if self.main.groups["contacts"].ready:
265 self.main.groups["list_choose"].setup(
267 [ (x[1], x[2] ) for x in self.main.groups["contacts"].phonebook],
268 self.current[self.selected][3],
271 elif result == _("reply"):
272 self.main.groups["text_edit"].setup(
275 self.current[self.selected][2], # title = number
276 self.current[self.selected][2], # reference = number
280 def cbMessagebookReply( self, result ):
281 logger.info( "retrieved messagebook: %s" % result )
283 self.messagebook = result
286 self.main.groups["main"].targets["sms"] = True
287 self.main.groups["main"].update()
288 if not self.newindex is None:
289 message = [x for x in self.messagebook if x[0] == self.newindex]
291 if message and self.main.current_group == self.main.groups["main"]:
293 if "read" in message[1]:
295 timestamp = message[4]["timestamp"]
298 timestamp = _("Unknown")
299 from_text = self.main.groups["contacts"].tryNumberToName( message[2] )
300 self.main.groups["text_show"].setup(
302 _("%s: %s<br>Date: %s<p>%s") % (
306 textblock_escape( message[3] ).replace( '\n', '<br>' )
309 if dbus_object.gsm_device_obj:
310 messagebookInfo = dbus_object.gsm_sim_iface.GetMessagebookInfo()
311 if messagebookInfo["used"] == messagebookInfo["last"]:
312 self.main.groups["alert"].activate( "<title>Warning</title>SIM Memory Full", [("OK")] )
314 def cbMessagebookError( self, e ):
315 logger.warning( "error while retrieving messagebook" )
318 def onIncomingMessage( self, index ):
319 logger.info( "new message! Retrieving messagebook..." )
320 self.newindex = index
322 dbus_object.gsm_sim_iface.RetrieveMessagebook(
324 reply_handler=self.cbMessagebookReply,
325 error_handler=self.cbMessagebookError
330 if not self.ready and not self.busy:
331 if dbus_object.gsm_device_obj:
332 logger.info( "retrieving messagebook..." )
333 dbus_object.gsm_sim_iface.RetrieveMessagebook(
335 reply_handler=self.cbMessagebookReply,
336 error_handler=self.cbMessagebookError
340 # Fake messagebook...
341 self.cbMessagebookReply( [
342 (0, "read", "+4544555", "Hello World!"),
343 (1, "read", "+456663443", "Zhone!"),
344 (2, "read", "+456663443", "Hi Guy\nGuess what, I now "+
345 "know to write multi-line SMSs.\nIsn't that "+
346 "nice?\n\nSome Buddy"),
347 (3, "read", "Flash SMS", "An SMS without digits. Strange, isn't it?"),
350 def onReadyStatus( self, status ):
351 logger.debug( "SIM is ready: %s" % status )
361 def updateList( self):
362 self.main.groups["contacts"].prepare()
363 self.pages = max( ( len( self.messagebook ) - 1 ) / 6 + 1, 1 )
364 if self.page >= self.pages:
365 self.page = self.pages - 1
368 self.current = self.messagebook[self.page*6:(self.page+1)*6]
369 text = u"".join( [u"□"]*self.page+[u"▣"]+[u"□"]*(self.pages-self.page-1) )
370 self.part_text_set( "pager", text )
371 for i in range( 0, len( self.current ) ):
372 main_text = self.main.groups["contacts"].tryNumberToName( self.current[i][2] )
373 self.part_text_set( "label_main_list_%i" % i, main_text )
374 sub_text = " ".join(self.current[i][3].splitlines())
375 self.part_text_set( "label_sub_list_%i" % i, u"(%s) %s" % ( self.current[i][1], sub_text ) )
376 for i in range( len( self.current ), 6):
377 self.part_text_set( "label_main_list_%i" % i, u"" )
378 self.part_text_set( "label_sub_list_%i" % i, u"" )
381 self.signal_emit( "deactivate_target_list_%i" % i, "" )
384 @edje.decorators.signal_callback( "mouse,clicked,1", "target_list_*" )
385 def on_edje_signal_button_list_pressed( self, emission, source ):
386 id = int( source.split( "_" )[-1] )
387 if self.selected == id:
389 if self.selected is not None:
390 self.signal_emit( "deactivate_target_list_%i" % self.selected, "" )
391 self.signal_emit( "activate_target_list_%i" % id, "" )
394 @edje.decorators.signal_callback( "mouse,clicked,1", "button_action_left" )
395 def on_edje_signal_button_action_left_pressed( self, emission, source ):
399 @edje.decorators.signal_callback( "mouse,clicked,1", "button_action_right" )
400 def on_edje_signal_button_action_right_pressed( self, emission, source ):
404 @edje.decorators.signal_callback( "mouse,clicked,1", "button_action_open" )
405 def on_edje_signal_button_action_open_pressed( self, emission, source ):
406 if self.selected is not None:
407 if "read" in self.current[self.selected][1]:
409 timestamp = self.current[self.selected][4]["timestamp"]
412 timestamp = _("Unknown")
413 from_text = self.main.groups["contacts"].tryNumberToName( self.current[self.selected][2] )
414 self.main.groups["text_show"].setup(
416 _("%s: %s<br>Date: %s<p>%s") % (
420 textblock_escape( self.current[self.selected][3] ).replace( '\n', '<br>' )
424 @edje.decorators.signal_callback( "mouse,clicked,1", "button_bottom_middle" )
425 def on_edje_signal_button_bottom_middle_pressed( self, emission, source ):
426 self.main.groups["menu"].activate( ( _("send"), _("delete"), _("forward"), _("reply") ), self.cbMenu )
427 self.main.groups["menu"].part_text_set( "target_label_cancel", _("cancel") )
431 static int main (string[] args) {
433 // Gst.init (ref args);
436 sbus = DBus.Bus.get(DBus.BusType.SYSTEM);
438 // Core infrastructure
439 // zavai.config = new zavai.Config();
440 // zavai.config.argv0 = args[0];
441 // zavai.registry = new zavai.Registry();
443 // Additional infrastructure
448 var gr = new GSMReceive();
451 gr.dump_message(args[1].to_int());
455 // zavai.info("Shutting down")
456 // zavai.registry.shutdown();