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