Simplified the test script
[gregoa/zavai.git] / test / test-gsm-receive.vala
1 /*
2  * test-gsm-receive - Play with receiving GSM data
3  *
4  * Copyright (C) 2010  Enrico Zini <enrico@enricozini.org>
5  *
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.
10  *
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.
15  *
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
19  */
20
21 using GLib;
22
23 public DBus.Connection sbus;
24
25 //string VERSION = "0.1";
26
27 public class GSMReceive: Object //, zavai.Resource
28 {
29     public dynamic DBus.Object device;
30     public dynamic DBus.Object network;
31     public dynamic DBus.Object call;
32
33     public GSMReceive()
34     {
35         //zavai.gsm.gsm.request("GSMReceive");
36
37         device = sbus.get_object(
38                     "org.freesmartphone.ogsmd",
39                     "/org/freesmartphone/GSM/Device",
40                     "org.freesmartphone.GSM.Device");
41
42         network = sbus.get_object(
43             "org.freesmartphone.ogsmd", 
44             "/org/freesmartphone/GSM/Device",
45             "org.freesmartphone.GSM.Network");
46
47         call = sbus.get_object(
48                 "org.freesmartphone.ogsmd",
49                 "/org/freesmartphone/GSM/Device",
50                 "org.freesmartphone.GSM.Call");
51
52         stderr.printf("Registering\n");
53         network.Register();
54         stderr.printf("Registered\n");
55
56         stderr.printf("Antenna is %s\n", device.GetAntennaPower() ? "on" : "off");
57         stderr.printf("Signal strength: %d\n", network.GetSignalStrength());
58         stderr.printf("Calling identification: %s\n", network.GetCallingIdentification());
59
60         network.Status += on_network_Status;
61         network.SignalStrength += on_network_SignalStrength;
62         call.CallStatus += on_call_Status;
63     }
64
65     public void shutdown()
66     {
67         //zavai.gsm.gsm.release("GSMReceive");
68     }
69
70     public void on_network_SignalStrength(int strength)
71     {
72         stderr.printf("SIGNAL STRENGTH %d\n", strength);
73     }
74
75     public void on_network_Status(GLib.HashTable<string, GLib.Value?> status)
76     {
77         stderr.printf("NETWORK STATUS\n");
78
79         // dbg("cbNetworkStatus %s" % formatDict(status))
80     }
81
82     public void on_call_Status(int index, string status, GLib.HashTable<string, GLib.Value?> properties)
83     {
84         stderr.printf("CALL STATUS %d %s\n", index, status);
85         /*
86         dbg("cbCallStatus %d, %s, %s" % (id, status, formatDict(properties)))
87         self.status = status
88         if status == "incoming":
89             if "peer" in properties and properties["peer"] == "+358942832031":
90                 self.gsm_call_iface.ReleaseAll()
91                 os.system("kapula-debug-call-handler &")
92             else:
93                 os.system("alsactl restore -f /etc/alsa-scenarios/stereoout-maxvolume.state")
94                 os.system("vibrator-start")
95                 os.system("ringtone-start")
96                 os.system("ledctrl --on-time 400 --off-time 200 gta02-aux:red");
97         if status == "release":
98             os.system("ringtone-stop")
99             os.system("vibrator-stop")
100             os.system("ledctrl --off gta02-aux:red");
101         */
102     }
103
104
105 /*
106         def onIncomingUssd( self, mode, message ):
107                 logger.info( "USSD Message: %s" % message )
108                         self.main.groups["alert"].activate( "<title>Operator Message</title>%s" % message, [("OK")] )
109     def onCallStatus( self, id, status, properties ):
110         self.call = id
111         self.update_status(status)
112         if not status in ["release"]:
113             if "peer" in properties:
114                 self.part_text_set( "label", self.main.groups["contacts"].tryNumberToName( properties[ "peer" ] ) )
115                 self.part_text_set( "sublabel", properties[ "peer" ] )
116             else:
117                 self.part_text_set( "label", _("unknown number") )
118                 self.part_text_set( "sublabel", "" )
119
120     @edje.decorators.signal_callback( "mouse,clicked,1", "button_*" )
121     def on_edje_signal_dialer_button_pressed(self, emission, source):
122         key = source.split("_", 1)[1]
123         if key in ("0", "1", "2", "3", "4", "5", "6", "7", "8", "9"):
124             dbus_object.gsm_call_iface.SendDtmf( key )
125             self.text.append(key)
126         elif key in "star":
127             dbus_object.gsm_call_iface.SendDtmf( "*" )
128             self.text.append("*")
129         elif key in "hash":
130             dbus_object.gsm_call_iface.SendDtmf( "#" )
131             self.text += "#"
132         # The trailing whitespace is a workaround for the one char invisible
133         # bug due to some problems with scaling of text parts.
134         self.part_text_set("label", "".join(self.text)+" ")
135
136     @edje.decorators.signal_callback("call_button_pressed", "button_right")
137     def on_edje_signal_call_button_right_pressed(self, emission, source):
138         self.main.transition_to("call")
139
140     def sendMessage( self, index ):
141         logger.info( "trying to send message w/ index %d..." % index )
142         dbus_object.gsm_sim_iface.SendStoredMessage( index, reply_handler=self.cbSendReply, error_handler=self.cbSendError )
143
144     def cbSendReply( self, reference, timestamp ):
145         logger.info( "sent message successfully w/ reference number %d (timestamp: %s)" % ( reference, timestamp ) )
146
147     def cbSendError( self, e ):
148         logger.error( "could not send message. leaving in outgoing. error was: %s" % e )
149
150     def cbStoreReply( self, result ):
151         logger.info( "stored message lives at SIM position %d" % result )
152         self.sendMessage( result )
153         if not self.busy:
154             dbus_object.gsm_sim_iface.RetrieveMessagebook(
155                 "all",
156                 reply_handler=self.cbMessagebookReply,
157                 error_handler=self.cbMessagebookError
158             )
159             self.busy = True
160
161     def cbStoreError( self, e ):
162         logger.warning( "error while storing message - %s" % e.get_dbus_name() )
163         if e.get_dbus_name() == "org.freesmartphone.GSM.SIM.MemoryFull":
164             self.main.groups["alert"].activate( "<title>Failed to send message</title>SIM Memory Full", [("OK")] )
165
166     def cbSend1( self, selected, cb_data ):
167         self.main.groups["text_edit"].setup(
168             "sms",
169             "", # text
170             selected[0], # title
171             selected[1], # reference
172             self.cbSend2
173         )
174
175     def cbSend2( self, text, number ):
176         if dbus_object.gsm_device_obj:
177             dbus_object.gsm_sim_iface.StoreMessage(
178                 number, text, {},
179                 reply_handler=self.cbStoreReply,
180                 error_handler=self.cbStoreError
181             )
182
183     def cbDelete( self, result, reference ):
184         if result == "abort":
185             return
186         if dbus_object.gsm_device_obj:
187             dbus_object.gsm_sim_iface.DeleteMessage(
188                 reference
189             )
190         for i in range( len( self.messagebook ) ):
191             if self.messagebook[i][0] == reference:
192                 del self.messagebook[i]
193                 break
194         self.updateList()
195
196     def cbForward( self, selected, text ):
197         if dbus_object.gsm_device_obj:
198             dbus_object.gsm_sim_iface.StoreMessage(
199                 selected[1], text, {},
200                 reply_handler=self.cbStoreReply,
201                 error_handler=self.cbStoreError
202             )
203
204     def cbReply( self, text, number):
205         if dbus_object.gsm_device_obj:
206             dbus_object.gsm_sim_iface.StoreMessage(
207                 number, text, {},
208                 reply_handler=self.cbStoreReply,
209                 error_handler=self.cbStoreError
210             )
211
212     def cbMenu( self, result ):
213         if result == _("send"):
214             self.main.groups["contacts"].prepare()
215             if self.main.groups["contacts"].ready:
216                 self.main.groups["list_choose"].setup(
217                     "sms",
218                     [ (x[1], x[2]) for x in  self.main.groups["contacts"].phonebook],
219                     None,
220                     self.cbSend1
221                 )
222         elif result == _("delete"):
223             self.main.groups["alert"].activate(
224                 _("delete?"),
225                 (_("abort"), _("delete")),
226                 self.current[self.selected][0], # reference
227                 self.cbDelete
228             )
229         elif result == _("forward"):
230             self.main.groups["contacts"].prepare()
231             if self.main.groups["contacts"].ready:
232                 self.main.groups["list_choose"].setup(
233                     "sms",
234                     [ (x[1], x[2] ) for x in  self.main.groups["contacts"].phonebook],
235                     self.current[self.selected][3],
236                     self.cbForward
237                 )
238         elif result == _("reply"):
239             self.main.groups["text_edit"].setup(
240                 "sms",
241                 "", # text
242                 self.current[self.selected][2], # title = number
243                 self.current[self.selected][2], # reference = number
244                 self.cbReply
245             )
246
247     def cbMessagebookReply( self, result ):
248         logger.info( "retrieved messagebook: %s" % result )
249         self.busy = False
250         self.messagebook = result
251         self.ready = True
252         self.updateList()
253         self.main.groups["main"].targets["sms"] = True
254         self.main.groups["main"].update()
255         if not self.newindex is None:
256             message = [x for x in self.messagebook if x[0] == self.newindex]
257             self.newindex = None
258             if message and self.main.current_group == self.main.groups["main"]:
259                 message = message[0]
260                 if "read" in message[1]:
261                     from_to = _("From")
262                     timestamp = message[4]["timestamp"]
263                 else:
264                     from_to = _("To")
265                     timestamp = _("Unknown")
266                 from_text = self.main.groups["contacts"].tryNumberToName( message[2] )
267                 self.main.groups["text_show"].setup(
268                     "sms",
269                     _("%s: %s<br>Date: %s<p>%s") % (
270                         from_to,
271                         from_text,
272                         timestamp,
273                         textblock_escape( message[3] ).replace( '\n', '<br>' )
274                     )
275                 )
276             if dbus_object.gsm_device_obj:
277                 messagebookInfo = dbus_object.gsm_sim_iface.GetMessagebookInfo()
278                 if messagebookInfo["used"] == messagebookInfo["last"]:
279                     self.main.groups["alert"].activate( "<title>Warning</title>SIM Memory Full", [("OK")] )
280
281     def cbMessagebookError( self, e ):
282         logger.warning( "error while retrieving messagebook" )
283         self.busy = False
284
285     def onIncomingMessage( self, index ):
286         logger.info( "new message! Retrieving messagebook..." )
287         self.newindex = index
288         if not self.busy:
289             dbus_object.gsm_sim_iface.RetrieveMessagebook(
290                 "all",
291                 reply_handler=self.cbMessagebookReply,
292                 error_handler=self.cbMessagebookError
293             )
294             self.busy = True
295
296     def prepare( self ):
297         if not self.ready and not self.busy:
298             if dbus_object.gsm_device_obj:
299                 logger.info( "retrieving messagebook..." )
300                 dbus_object.gsm_sim_iface.RetrieveMessagebook(
301                     "all",
302                     reply_handler=self.cbMessagebookReply,
303                     error_handler=self.cbMessagebookError
304                 )
305                 self.busy = True
306             else:
307                 # Fake messagebook...
308                 self.cbMessagebookReply( [
309                     (0, "read", "+4544555", "Hello World!"),
310                     (1, "read", "+456663443", "Zhone!"),
311                     (2, "read", "+456663443", "Hi Guy\nGuess what, I now "+
312                         "know to write multi-line SMSs.\nIsn't that "+
313                         "nice?\n\nSome Buddy"),
314                     (3, "read", "Flash SMS", "An SMS without digits. Strange, isn't it?"),
315                 ] )
316
317     def onReadyStatus( self, status ):
318         logger.debug( "SIM is ready: %s" % status )
319         if status:
320             # Force update
321             self.ready = False
322             self.prepare()
323
324     def onShow( self ):
325         self.prepare()
326         self.updateList()
327
328     def updateList( self):
329         self.main.groups["contacts"].prepare()
330         self.pages = max( ( len( self.messagebook ) - 1 ) / 6 + 1, 1 )
331         if self.page >= self.pages:
332             self.page = self.pages - 1
333         if self.page < 0:
334             self.page = 0
335         self.current = self.messagebook[self.page*6:(self.page+1)*6]
336         text = u"".join( [u"□"]*self.page+[u"▣"]+[u"□"]*(self.pages-self.page-1) )
337         self.part_text_set( "pager", text )
338         for i in range( 0, len( self.current ) ):
339             main_text = self.main.groups["contacts"].tryNumberToName( self.current[i][2] )
340             self.part_text_set( "label_main_list_%i" % i, main_text )
341             sub_text = " ".join(self.current[i][3].splitlines())
342             self.part_text_set( "label_sub_list_%i" % i, u"(%s) %s" % ( self.current[i][1], sub_text ) )
343         for i in range( len( self.current ), 6):
344             self.part_text_set( "label_main_list_%i" % i, u"" )
345             self.part_text_set( "label_sub_list_%i" % i, u"" )
346         self.selected = None
347         for i in range( 6 ):
348             self.signal_emit( "deactivate_target_list_%i" % i, "" )
349
350
351     @edje.decorators.signal_callback( "mouse,clicked,1", "target_list_*" )
352     def on_edje_signal_button_list_pressed( self, emission, source ):
353         id = int( source.split( "_" )[-1] )
354         if self.selected == id:
355             return
356         if self.selected is not None:
357             self.signal_emit( "deactivate_target_list_%i" % self.selected, "" )
358         self.signal_emit( "activate_target_list_%i" % id, "" )
359         self.selected = id
360
361     @edje.decorators.signal_callback( "mouse,clicked,1", "button_action_left" )
362     def on_edje_signal_button_action_left_pressed( self, emission, source ):
363         self.page -= 1
364         self.updateList()
365
366     @edje.decorators.signal_callback( "mouse,clicked,1", "button_action_right" )
367     def on_edje_signal_button_action_right_pressed( self, emission, source ):
368         self.page += 1
369         self.updateList()
370
371     @edje.decorators.signal_callback( "mouse,clicked,1", "button_action_open" )
372     def on_edje_signal_button_action_open_pressed( self, emission, source ):
373         if self.selected is not None:
374             if "read" in self.current[self.selected][1]:
375                 from_to = _("From")
376                 timestamp = self.current[self.selected][4]["timestamp"]
377             else:
378                 from_to = _("To")
379                 timestamp = _("Unknown")
380             from_text = self.main.groups["contacts"].tryNumberToName( self.current[self.selected][2] )
381             self.main.groups["text_show"].setup(
382                 "sms",
383                 _("%s: %s<br>Date: %s<p>%s") % (
384                     from_to,
385                     from_text,
386                     timestamp,
387                     textblock_escape( self.current[self.selected][3] ).replace( '\n', '<br>' )
388                 )
389             )
390
391     @edje.decorators.signal_callback( "mouse,clicked,1", "button_bottom_middle" )
392     def on_edje_signal_button_bottom_middle_pressed( self, emission, source ):
393         self.main.groups["menu"].activate( ( _("send"), _("delete"), _("forward"), _("reply") ), self.cbMenu )
394         self.main.groups["menu"].part_text_set( "target_label_cancel", _("cancel") )
395 */
396 }
397
398 static int main (string[] args) {
399         Gtk.init (ref args);
400     // Gst.init (ref args);
401
402         // Set up zavai
403         sbus = DBus.Bus.get(DBus.BusType.SYSTEM);
404
405     // Core infrastructure
406 //      zavai.config = new zavai.Config();
407 //      zavai.config.argv0 = args[0];
408 //      zavai.registry = new zavai.Registry();
409
410     // Additional infrastructure
411         //zavai.gsm.init();
412         //zavai.log.init();
413
414     // PLAY here
415     var gr = new GSMReceive();
416
417         Gtk.main();
418
419         // zavai.info("Shutting down")
420         // zavai.registry.shutdown();
421
422         return 0;
423 }