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