1 /* $Id$ */
2 /* Copyright (c) 2011-2015 Pierre Pronchery <khorben@defora.org> */
3 /* This file is part of DeforaOS Desktop Phone */
4 /* This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation, version 3 of the License.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>. */
15 /* FIXME:
16 * - check if it resets the modem on "OK" (and if so, avoid it) */
17
18
19
20 #include <stdlib.h>
21 #include <string.h>
22 #include <gtk/gtk.h>
23 #include <System.h>
24 #ifdef PROGNAME
25 # include <Desktop.h>
26 #endif
27 #include "Phone.h"
28 #include "../../config.h"
29
30 #ifndef PREFIX
31 # define PREFIX "/usr/local"
32 #endif
33 #ifndef SYSCONFDIR
34 # define SYSCONFDIR PREFIX "/etc"
35 #endif
36
37
38 /* GPRS */
39 /* private */
40 /* types */
41 typedef struct _PhonePlugin
42 {
43 PhonePluginHelper * helper;
44 guint source;
45 gboolean roaming;
46 gboolean connected;
47 size_t in;
48 size_t out;
49 size_t glin;
50 size_t glout;
51 char * _operator;
52
53 gboolean active;
54 GtkWidget * window;
55 GtkWidget * notebook;
56 GtkWidget * attach;
57 GtkWidget * apn;
58 GtkWidget * username;
59 GtkWidget * password;
60 #ifndef PROGNAME
61 GtkWidget * defaults;
62 #endif
63 GtkWidget * connect;
64 GtkWidget * st_image;
65 GtkWidget * st_label;
66 GtkWidget * st_in;
67 GtkWidget * st_out;
68 GtkWidget * st_glin;
69 GtkWidget * st_glout;
70 #if GTK_CHECK_VERSION(2, 10, 0)
71 GtkWidget * systray;
72 GtkStatusIcon * icon;
73 #endif
74 } GPRS;
75
76
77 /* prototypes */
78 /* plug-in */
79 static GPRS * _gprs_init(PhonePluginHelper * helper);
80 static void _gprs_destroy(GPRS * gprs);
81 static int _gprs_event(GPRS * gprs, PhoneEvent * event);
82 static void _gprs_settings(GPRS * gprs);
83
84 /* accessors */
85 static void _gprs_set_connected(GPRS * gprs, gboolean connected,
86 char const * message, size_t in, size_t out);
87
88 /* useful */
89 static int _gprs_access_point(GPRS * gprs);
90 static int _gprs_connect(GPRS * gprs);
91
92 static void _gprs_counters_load(GPRS * gprs);
93 static void _gprs_counters_save(GPRS * gprs);
94
95 static int _gprs_disconnect(GPRS * gprs);
96
97 static int _gprs_load_defaults(GPRS * gprs);
98 static int _gprs_load_operator(GPRS * gprs, char const * _operator);
99
100 /* callbacks */
101 static void _gprs_on_activate(gpointer data);
102 static void _gprs_on_load_defaults(gpointer data);
103 static void _gprs_on_popup_menu(GtkStatusIcon * icon, guint button,
104 guint time, gpointer data);
105 static gboolean _gprs_on_timeout(gpointer data);
106
107
108 /* public */
109 /* variables */
110 PhonePluginDefinition plugin =
111 {
112 "Dial-up networking",
113 "phone-gprs",
114 NULL,
115 _gprs_init,
116 _gprs_destroy,
117 _gprs_event,
118 _gprs_settings
119 };
120
121
122 /* private */
123 /* functions */
124 /* plug-in */
125 /* gprs_init */
_gprs_init(PhonePluginHelper * helper)126 static GPRS * _gprs_init(PhonePluginHelper * helper)
127 {
128 GPRS * gprs;
129 #if GTK_CHECK_VERSION(2, 10, 0)
130 char const * p;
131 gboolean active;
132 #endif
133
134 if((gprs = object_new(sizeof(*gprs))) == NULL)
135 return NULL;
136 gprs->helper = helper;
137 gprs->source = 0;
138 gprs->roaming = FALSE;
139 gprs->connected = FALSE;
140 gprs->in = 0;
141 gprs->out = 0;
142 gprs->glin = 0;
143 gprs->glout = 0;
144 gprs->_operator = NULL;
145 gprs->active = FALSE;
146 gprs->window = NULL;
147 #if GTK_CHECK_VERSION(2, 10, 0)
148 gprs->icon = gtk_status_icon_new_from_icon_name("phone-gprs");
149 # if GTK_CHECK_VERSION(2, 16, 0)
150 gtk_status_icon_set_tooltip_text(gprs->icon, "Not connected");
151 # endif
152 # if GTK_CHECK_VERSION(2, 18, 0)
153 gtk_status_icon_set_title(gprs->icon, "Dial-up networking");
154 # if GTK_CHECK_VERSION(2, 20, 0)
155 gtk_status_icon_set_name(gprs->icon, "phone-gprs");
156 # endif
157 # endif
158 g_signal_connect_swapped(gprs->icon, "activate", G_CALLBACK(
159 _gprs_on_activate), gprs);
160 g_signal_connect(gprs->icon, "popup-menu", G_CALLBACK(
161 _gprs_on_popup_menu), gprs);
162 active = ((p = helper->config_get(helper->phone, "gprs", "systray"))
163 != NULL && strtoul(p, NULL, 10) != 0) ? TRUE : FALSE;
164 gtk_status_icon_set_visible(gprs->icon, active);
165 #endif
166 _gprs_counters_load(gprs);
167 return gprs;
168 }
169
170
171 /* gprs_destroy */
_gprs_destroy(GPRS * gprs)172 static void _gprs_destroy(GPRS * gprs)
173 {
174 free(gprs->_operator);
175 _gprs_counters_save(gprs);
176 #if GTK_CHECK_VERSION(2, 10, 0)
177 g_object_unref(gprs->icon);
178 #endif
179 if(gprs->source != 0)
180 g_source_remove(gprs->source);
181 if(gprs->window != NULL)
182 gtk_widget_destroy(gprs->window);
183 object_delete(gprs);
184 }
185
186
187 /* gprs_event */
188 static int _gprs_event_modem(GPRS * gprs, ModemEvent * event);
189 static void _gprs_event_modem_operator(GPRS * gprs, char const * _operator);
190
_gprs_event(GPRS * gprs,PhoneEvent * event)191 static int _gprs_event(GPRS * gprs, PhoneEvent * event)
192 {
193 switch(event->type)
194 {
195 case PHONE_EVENT_TYPE_MODEM_EVENT:
196 return _gprs_event_modem(gprs,
197 event->modem_event.event);
198 case PHONE_EVENT_TYPE_OFFLINE:
199 case PHONE_EVENT_TYPE_UNAVAILABLE:
200 gprs->roaming = FALSE;
201 return 0;
202 default: /* not relevant */
203 return 0;
204 }
205 }
206
_gprs_event_modem(GPRS * gprs,ModemEvent * event)207 static int _gprs_event_modem(GPRS * gprs, ModemEvent * event)
208 {
209 gboolean connected;
210
211 switch(event->type)
212 {
213 case MODEM_EVENT_TYPE_CONNECTION:
214 connected = event->connection.connected;
215 _gprs_set_connected(gprs, connected, NULL,
216 event->connection.in,
217 event->connection.out);
218 break;
219 case MODEM_EVENT_TYPE_REGISTRATION:
220 /* operator */
221 _gprs_event_modem_operator(gprs,
222 event->registration._operator);
223 /* roaming */
224 gprs->roaming = event->registration.roaming;
225 /* status */
226 if(gprs->active != FALSE)
227 break;
228 if(event->registration.status
229 != MODEM_REGISTRATION_STATUS_REGISTERED)
230 break;
231 gprs->active = TRUE;
232 /* FIXME optionally force GPRS registration */
233 break;
234 default:
235 break;
236 }
237 return 0;
238 }
239
_gprs_event_modem_operator(GPRS * gprs,char const * _operator)240 static void _gprs_event_modem_operator(GPRS * gprs, char const * _operator)
241 {
242 PhonePluginHelper * helper = gprs->helper;
243 char const * p;
244
245 free(gprs->_operator);
246 gprs->_operator = (_operator != NULL) ? strdup(_operator) : NULL;
247 if(gprs->window == NULL)
248 return;
249 #ifndef PROGNAME
250 gtk_widget_set_sensitive(gprs->defaults, (gprs->_operator != NULL)
251 ? TRUE : FALSE);
252 #endif
253 /* FIXME also load the defaults when creating the window if relevant */
254 if(((p = gtk_entry_get_text(GTK_ENTRY(gprs->apn))) == NULL
255 || strlen(p) == 0)
256 && ((p = gtk_entry_get_text(GTK_ENTRY(gprs->username)))
257 == NULL || strlen(p) == 0)
258 && ((p = gtk_entry_get_text(GTK_ENTRY(gprs->password)))
259 == NULL || strlen(p) == 0)
260 && helper->config_get(helper->phone, "gprs", "apn")
261 == NULL
262 && helper->config_get(helper->phone, "gprs", "username")
263 == NULL
264 && helper->config_get(helper->phone, "gprs", "password")
265 == NULL)
266 _gprs_load_defaults(gprs);
267 }
268
269
270 /* gprs_settings */
271 static GtkWidget * _settings_preferences(GPRS * gprs);
272 static GtkWidget * _settings_status(GPRS * gprs);
273 /* callbacks */
274 static void _settings_on_apply(gpointer data);
275 static void _settings_on_cancel(gpointer data);
276 static gboolean _settings_on_closex(gpointer data);
277 static void _settings_on_connect(gpointer data);
278 #ifdef PROGNAME
279 static void _settings_on_help(gpointer data);
280 #endif
281 static void _settings_on_ok(gpointer data);
282 static void _settings_on_reset(gpointer data);
283
_gprs_settings(GPRS * gprs)284 static void _gprs_settings(GPRS * gprs)
285 {
286 GtkWidget * vbox;
287 GtkWidget * bbox;
288 GtkWidget * widget;
289
290 if(gprs->window != NULL)
291 {
292 gtk_notebook_set_current_page(GTK_NOTEBOOK(gprs->notebook), 0);
293 gtk_window_present(GTK_WINDOW(gprs->window));
294 return;
295 }
296 gprs->window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
297 gtk_container_set_border_width(GTK_CONTAINER(gprs->window), 4);
298 gtk_window_set_default_size(GTK_WINDOW(gprs->window), 200, 300);
299 #if GTK_CHECK_VERSION(2, 6, 0)
300 gtk_window_set_icon_name(GTK_WINDOW(gprs->window), "phone-gprs");
301 #endif
302 gtk_window_set_title(GTK_WINDOW(gprs->window), "Dial-up networking");
303 g_signal_connect_swapped(gprs->window, "delete-event", G_CALLBACK(
304 _settings_on_closex), gprs);
305 #if GTK_CHECK_VERSION(3, 0, 0)
306 vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 4);
307 #else
308 vbox = gtk_vbox_new(FALSE, 4);
309 #endif
310 gprs->notebook = gtk_notebook_new();
311 /* preferences */
312 widget = _settings_preferences(gprs);
313 gtk_notebook_append_page(GTK_NOTEBOOK(gprs->notebook), widget,
314 gtk_label_new("Preferences"));
315 /* status */
316 widget = _settings_status(gprs);
317 gtk_notebook_append_page(GTK_NOTEBOOK(gprs->notebook), widget,
318 gtk_label_new("Status"));
319 gtk_box_pack_start(GTK_BOX(vbox), gprs->notebook, TRUE, TRUE, 0);
320 /* button box */
321 #if GTK_CHECK_VERSION(3, 0, 0)
322 bbox = gtk_button_box_new(GTK_ORIENTATION_HORIZONTAL);
323 #else
324 bbox = gtk_hbutton_box_new();
325 #endif
326 gtk_button_box_set_layout(GTK_BUTTON_BOX(bbox), GTK_BUTTONBOX_END);
327 gtk_box_set_spacing(GTK_BOX(bbox), 4);
328 #ifdef PROGNAME
329 widget = gtk_button_new_from_stock(GTK_STOCK_HELP);
330 g_signal_connect_swapped(widget, "clicked", G_CALLBACK(
331 _settings_on_help), gprs);
332 gtk_container_add(GTK_CONTAINER(bbox), widget);
333 #endif
334 widget = gtk_button_new_from_stock(GTK_STOCK_CANCEL);
335 g_signal_connect_swapped(widget, "clicked", G_CALLBACK(
336 _settings_on_cancel), gprs);
337 gtk_container_add(GTK_CONTAINER(bbox), widget);
338 widget = gtk_button_new_from_stock(GTK_STOCK_OK);
339 g_signal_connect_swapped(widget, "clicked", G_CALLBACK(_settings_on_ok),
340 gprs);
341 gtk_container_add(GTK_CONTAINER(bbox), widget);
342 gtk_box_pack_end(GTK_BOX(vbox), bbox, FALSE, TRUE, 0);
343 gtk_container_add(GTK_CONTAINER(gprs->window), vbox);
344 _settings_on_cancel(gprs);
345 _gprs_on_timeout(gprs);
346 gtk_widget_show_all(gprs->window);
347 }
348
_settings_preferences(GPRS * gprs)349 static GtkWidget * _settings_preferences(GPRS * gprs)
350 {
351 GtkSizeGroup * group;
352 GtkWidget * vbox;
353 GtkWidget * hbox;
354 GtkWidget * frame;
355 GtkWidget * vbox2;
356 GtkWidget * widget;
357
358 #if GTK_CHECK_VERSION(3, 0, 0)
359 vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 4);
360 #else
361 vbox = gtk_vbox_new(FALSE, 4);
362 #endif
363 /* attachment */
364 gprs->attach = gtk_check_button_new_with_label(
365 "Force GPRS registration");
366 gtk_box_pack_start(GTK_BOX(vbox), gprs->attach, FALSE, TRUE, 0);
367 /* systray */
368 gprs->systray = gtk_check_button_new_with_label("Show in system tray");
369 gtk_box_pack_start(GTK_BOX(vbox), gprs->systray, FALSE, TRUE, 0);
370 /* credentials */
371 frame = gtk_frame_new("Credentials");
372 #if GTK_CHECK_VERSION(3, 0, 0)
373 vbox2 = gtk_box_new(GTK_ORIENTATION_VERTICAL, 4);
374 #else
375 vbox2 = gtk_vbox_new(FALSE, 4);
376 #endif
377 gtk_container_set_border_width(GTK_CONTAINER(vbox2), 4);
378 group = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
379 /* access point */
380 #if GTK_CHECK_VERSION(3, 0, 0)
381 hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 4);
382 #else
383 hbox = gtk_hbox_new(FALSE, 4);
384 #endif
385 widget = gtk_label_new("Access point:");
386 #if GTK_CHECK_VERSION(3, 0, 0)
387 g_object_set(widget, "halign", GTK_ALIGN_START, NULL);
388 #else
389 gtk_misc_set_alignment(GTK_MISC(widget), 0.0, 0.5);
390 #endif
391 gtk_size_group_add_widget(group, widget);
392 gtk_box_pack_start(GTK_BOX(hbox), widget, FALSE, TRUE, 0);
393 gprs->apn = gtk_entry_new();
394 gtk_box_pack_start(GTK_BOX(hbox), gprs->apn, TRUE, TRUE, 0);
395 gtk_box_pack_start(GTK_BOX(vbox2), hbox, FALSE, TRUE, 0);
396 /* username */
397 #if GTK_CHECK_VERSION(3, 0, 0)
398 hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 4);
399 #else
400 hbox = gtk_hbox_new(FALSE, 4);
401 #endif
402 widget = gtk_label_new("Username:");
403 #if GTK_CHECK_VERSION(3, 0, 0)
404 g_object_set(widget, "halign", GTK_ALIGN_START, NULL);
405 #else
406 gtk_misc_set_alignment(GTK_MISC(widget), 0.0, 0.5);
407 #endif
408 gtk_size_group_add_widget(group, widget);
409 gtk_box_pack_start(GTK_BOX(hbox), widget, FALSE, TRUE, 0);
410 gprs->username = gtk_entry_new();
411 gtk_box_pack_start(GTK_BOX(hbox), gprs->username, TRUE, TRUE, 0);
412 gtk_box_pack_start(GTK_BOX(vbox2), hbox, FALSE, TRUE, 0);
413 /* password */
414 #if GTK_CHECK_VERSION(3, 0, 0)
415 hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 4);
416 #else
417 hbox = gtk_hbox_new(FALSE, 4);
418 #endif
419 widget = gtk_label_new("Password:");
420 #if GTK_CHECK_VERSION(3, 0, 0)
421 g_object_set(widget, "halign", GTK_ALIGN_START, NULL);
422 #else
423 gtk_misc_set_alignment(GTK_MISC(widget), 0.0, 0.5);
424 #endif
425 gtk_size_group_add_widget(group, widget);
426 gtk_box_pack_start(GTK_BOX(hbox), widget, FALSE, TRUE, 0);
427 gprs->password = gtk_entry_new();
428 gtk_entry_set_visibility(GTK_ENTRY(gprs->password), FALSE);
429 gtk_box_pack_start(GTK_BOX(hbox), gprs->password, TRUE, TRUE, 0);
430 gtk_box_pack_start(GTK_BOX(vbox2), hbox, FALSE, TRUE, 0);
431 #ifndef PROGNAME
432 /* defaults */
433 # if GTK_CHECK_VERSION(3, 0, 0)
434 hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 4);
435 # else
436 hbox = gtk_hbox_new(FALSE, 4);
437 # endif
438 gprs->defaults = gtk_button_new_with_label("Load defaults");
439 gtk_widget_set_sensitive(gprs->defaults, (gprs->_operator != NULL)
440 ? TRUE : FALSE);
441 g_signal_connect_swapped(gprs->defaults, "clicked", G_CALLBACK(
442 _gprs_on_load_defaults), gprs);
443 gtk_box_pack_end(GTK_BOX(hbox), gprs->defaults, FALSE, TRUE, 0);
444 gtk_box_pack_end(GTK_BOX(vbox2), hbox, FALSE, TRUE, 0);
445 #endif
446 gtk_container_add(GTK_CONTAINER(frame), vbox2);
447 gtk_box_pack_start(GTK_BOX(vbox), frame, TRUE, TRUE, 0);
448 return vbox;
449 }
450
_settings_status(GPRS * gprs)451 static GtkWidget * _settings_status(GPRS * gprs)
452 {
453 GtkWidget * vbox;
454 GtkWidget * hbox;
455 GtkWidget * widget;
456 GtkWidget * bbox;
457
458 #if GTK_CHECK_VERSION(3, 0, 0)
459 vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 4);
460 #else
461 vbox = gtk_vbox_new(FALSE, 4);
462 #endif
463 /* details */
464 widget = gtk_frame_new("Details");
465 #if GTK_CHECK_VERSION(3, 0, 0)
466 bbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 4);
467 #else
468 bbox = gtk_vbox_new(FALSE, 4);
469 #endif
470 gtk_container_set_border_width(GTK_CONTAINER(bbox), 4);
471 #if GTK_CHECK_VERSION(3, 0, 0)
472 hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 4);
473 #else
474 hbox = gtk_hbox_new(FALSE, 4);
475 #endif
476 gprs->st_image = gtk_image_new_from_icon_name(GTK_STOCK_DISCONNECT,
477 GTK_ICON_SIZE_BUTTON);
478 gtk_box_pack_start(GTK_BOX(hbox), gprs->st_image, FALSE, TRUE, 0);
479 gprs->st_label = gtk_label_new("Not connected");
480 #if GTK_CHECK_VERSION(3, 0, 0)
481 g_object_set(gprs->st_label, "halign", GTK_ALIGN_START, NULL);
482 #else
483 gtk_misc_set_alignment(GTK_MISC(gprs->st_label), 0.0, 0.5);
484 #endif
485 gtk_box_pack_start(GTK_BOX(hbox), gprs->st_label, TRUE, TRUE, 0);
486 gtk_box_pack_start(GTK_BOX(bbox), hbox, FALSE, TRUE, 0);
487 gprs->st_in = gtk_label_new(NULL);
488 #if GTK_CHECK_VERSION(3, 0, 0)
489 g_object_set(gprs->st_in, "halign", GTK_ALIGN_START, NULL);
490 #else
491 gtk_misc_set_alignment(GTK_MISC(gprs->st_in), 0.0, 0.5);
492 #endif
493 gtk_widget_set_no_show_all(gprs->st_in, TRUE);
494 gtk_box_pack_start(GTK_BOX(bbox), gprs->st_in, FALSE, TRUE, 0);
495 gprs->st_out = gtk_label_new(NULL);
496 #if GTK_CHECK_VERSION(3, 0, 0)
497 g_object_set(gprs->st_out, "halign", GTK_ALIGN_START, NULL);
498 #else
499 gtk_misc_set_alignment(GTK_MISC(gprs->st_out), 0.0, 0.5);
500 #endif
501 gtk_widget_set_no_show_all(gprs->st_out, TRUE);
502 gtk_box_pack_start(GTK_BOX(bbox), gprs->st_out, FALSE, TRUE, 0);
503 gtk_container_add(GTK_CONTAINER(widget), bbox);
504 gtk_box_pack_start(GTK_BOX(vbox), widget, FALSE, TRUE, 0);
505 /* connect */
506 gprs->connect = gtk_button_new_from_stock(GTK_STOCK_CONNECT);
507 g_signal_connect_swapped(gprs->connect, "clicked", G_CALLBACK(
508 _settings_on_connect), gprs);
509 gtk_box_pack_start(GTK_BOX(vbox), gprs->connect, FALSE, TRUE, 0);
510 /* counters */
511 widget = gtk_frame_new("Counters");
512 #if GTK_CHECK_VERSION(3, 0, 0)
513 hbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 4);
514 #else
515 hbox = gtk_vbox_new(FALSE, 4);
516 #endif
517 gtk_container_set_border_width(GTK_CONTAINER(hbox), 4);
518 gprs->st_glin = gtk_label_new(NULL);
519 #if GTK_CHECK_VERSION(3, 0, 0)
520 g_object_set(gprs->st_glin, "halign", GTK_ALIGN_START, NULL);
521 #else
522 gtk_misc_set_alignment(GTK_MISC(gprs->st_glin), 0.0, 0.5);
523 #endif
524 gtk_box_pack_start(GTK_BOX(hbox), gprs->st_glin, FALSE, TRUE, 0);
525 gprs->st_glout = gtk_label_new(NULL);
526 #if GTK_CHECK_VERSION(3, 0, 0)
527 g_object_set(gprs->st_glout, "halign", GTK_ALIGN_START, NULL);
528 #else
529 gtk_misc_set_alignment(GTK_MISC(gprs->st_glout), 0.0, 0.5);
530 #endif
531 gtk_box_pack_start(GTK_BOX(hbox), gprs->st_glout, FALSE, TRUE, 0);
532 bbox = gtk_button_new_from_stock(GTK_STOCK_CLEAR);
533 g_signal_connect_swapped(bbox, "clicked", G_CALLBACK(
534 _settings_on_reset), gprs);
535 gtk_box_pack_start(GTK_BOX(hbox), bbox, FALSE, TRUE, 0);
536 gtk_container_add(GTK_CONTAINER(widget), hbox);
537 gtk_box_pack_start(GTK_BOX(vbox), widget, FALSE, TRUE, 0);
538 return vbox;
539 }
540
_settings_on_apply(gpointer data)541 static void _settings_on_apply(gpointer data)
542 {
543 GPRS * gprs = data;
544 PhonePluginHelper * helper = gprs->helper;
545 gboolean active;
546 char const * p;
547
548 active = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(gprs->attach));
549 helper->config_set(helper->phone, "gprs", "attach", active ? "1" : "0");
550 p = gtk_entry_get_text(GTK_ENTRY(gprs->apn));
551 helper->config_set(helper->phone, "gprs", "apn", p);
552 p = gtk_entry_get_text(GTK_ENTRY(gprs->username));
553 helper->config_set(helper->phone, "gprs", "username", p);
554 p = gtk_entry_get_text(GTK_ENTRY(gprs->password));
555 helper->config_set(helper->phone, "gprs", "password", p);
556 #if GTK_CHECK_VERSION(2, 10, 0)
557 active = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(gprs->systray));
558 helper->config_set(helper->phone, "gprs", "systray", active
559 ? "1" : "0");
560 gtk_status_icon_set_visible(gprs->icon, active);
561 #endif
562 _gprs_access_point(gprs);
563 _gprs_counters_save(gprs);
564 gprs->active = FALSE;
565 }
566
_settings_on_cancel(gpointer data)567 static void _settings_on_cancel(gpointer data)
568 {
569 GPRS * gprs = data;
570 PhonePluginHelper * helper = gprs->helper;
571 char const * p;
572 gboolean active;
573
574 gtk_widget_hide(gprs->window);
575 active = ((p = helper->config_get(helper->phone, "gprs", "attach"))
576 != NULL && strtoul(p, NULL, 10) != 0) ? TRUE : FALSE;
577 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(gprs->attach), active);
578 if((p = helper->config_get(helper->phone, "gprs", "apn")) == NULL)
579 p = "";
580 gtk_entry_set_text(GTK_ENTRY(gprs->apn), p);
581 if((p = helper->config_get(helper->phone, "gprs", "username")) == NULL)
582 p = "";
583 gtk_entry_set_text(GTK_ENTRY(gprs->username), p);
584 if((p = helper->config_get(helper->phone, "gprs", "password")) == NULL)
585 p = "";
586 gtk_entry_set_text(GTK_ENTRY(gprs->password), p);
587 #if GTK_CHECK_VERSION(2, 10, 0)
588 active = ((p = helper->config_get(helper->phone, "gprs", "systray"))
589 != NULL && strtoul(p, NULL, 10) != 0) ? TRUE : FALSE;
590 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(gprs->systray), active);
591 #endif
592 _gprs_set_connected(gprs, gprs->connected, NULL, gprs->in, gprs->out);
593 }
594
_settings_on_closex(gpointer data)595 static gboolean _settings_on_closex(gpointer data)
596 {
597 GPRS * gprs = data;
598
599 _settings_on_cancel(gprs);
600 return TRUE;
601 }
602
_settings_on_connect(gpointer data)603 static void _settings_on_connect(gpointer data)
604 {
605 GPRS * gprs = data;
606 int res;
607
608 _settings_on_apply(gprs);
609 res = gprs->connected ? _gprs_disconnect(gprs) : _gprs_connect(gprs);
610 if(res != 0)
611 gprs->helper->error(gprs->helper->phone, error_get(NULL), 1);
612 }
613
614 #ifdef PROGNAME
_settings_on_help(gpointer data)615 static void _settings_on_help(gpointer data)
616 {
617 desktop_help_contents(PACKAGE, PROGNAME);
618 }
619 #endif
620
_settings_on_ok(gpointer data)621 static void _settings_on_ok(gpointer data)
622 {
623 GPRS * gprs = data;
624
625 gtk_widget_hide(gprs->window);
626 _settings_on_apply(gprs);
627 }
628
_settings_on_reset(gpointer data)629 static void _settings_on_reset(gpointer data)
630 {
631 GPRS * gprs = data;
632
633 gprs->glin = 0;
634 gprs->glout = 0;
635 /* refresh the dialog box */
636 _gprs_set_connected(gprs, gprs->connected, NULL, gprs->in, gprs->out);
637 /* save in the configuration */
638 _gprs_counters_save(gprs);
639 }
640
641
642 /* accessors */
643 /* gprs_set_connected */
_gprs_set_connected(GPRS * gprs,gboolean connected,char const * message,size_t in,size_t out)644 static void _gprs_set_connected(GPRS * gprs, gboolean connected,
645 char const * message, size_t in, size_t out)
646 {
647 char buf[64];
648
649 gprs->connected = connected;
650 if(message == NULL)
651 message = connected ? "Connected" : "Not connected";
652 if(gprs->window == NULL)
653 return;
654 gtk_image_set_from_icon_name(GTK_IMAGE(gprs->st_image), connected
655 ? GTK_STOCK_CONNECT : GTK_STOCK_DISCONNECT,
656 GTK_ICON_SIZE_BUTTON);
657 gtk_label_set_text(GTK_LABEL(gprs->st_label), message);
658 gtk_button_set_label(GTK_BUTTON(gprs->connect), connected
659 ? GTK_STOCK_DISCONNECT : GTK_STOCK_CONNECT);
660 if(connected)
661 {
662 snprintf(buf, sizeof(buf), "Received: %lu kB (%lu kB/s)",
663 (unsigned long)in / 1024,
664 (unsigned long)(in - gprs->in) / 1024);
665 gtk_label_set_text(GTK_LABEL(gprs->st_in), buf);
666 snprintf(buf, sizeof(buf), "Sent: %lu kB (%lu kB/s)",
667 (unsigned long)out / 1024,
668 (unsigned long)(out - gprs->out) / 1024);
669 gtk_label_set_text(GTK_LABEL(gprs->st_out), buf);
670 gtk_widget_show(gprs->st_in);
671 gtk_widget_show(gprs->st_out);
672 #if GTK_CHECK_VERSION(2, 16, 0)
673 snprintf(buf, sizeof(buf), "%s\nReceived: %lu kB\nSent: %lu kB",
674 message, (unsigned long)in / 1024,
675 (unsigned long)out / 1024);
676 gtk_status_icon_set_tooltip_text(gprs->icon, buf);
677 #endif
678 gprs->in = in;
679 gprs->out = out;
680 if(gprs->source == 0)
681 gprs->source = g_timeout_add(1000, _gprs_on_timeout,
682 gprs);
683 }
684 else
685 {
686 if(gprs->source != 0)
687 g_source_remove(gprs->source);
688 gprs->source = 0;
689 gtk_widget_hide(gprs->st_in);
690 gtk_widget_hide(gprs->st_out);
691 #if GTK_CHECK_VERSION(2, 16, 0)
692 gtk_status_icon_set_tooltip_text(gprs->icon, message);
693 #endif
694 /* add the last known data to the global counters */
695 gprs->glin += gprs->in;
696 gprs->glout += gprs->out;
697 /* save in the configuration */
698 _gprs_counters_save(gprs);
699 /* reset the known data */
700 gprs->in = 0;
701 gprs->out = 0;
702 }
703 /* counters */
704 snprintf(buf, sizeof(buf), "Received: %lu kB", (gprs->glin + in)
705 / 1024);
706 gtk_label_set_text(GTK_LABEL(gprs->st_glin), buf);
707 snprintf(buf, sizeof(buf), "Sent: %lu kB", (gprs->glout + out) / 1024);
708 gtk_label_set_text(GTK_LABEL(gprs->st_glout), buf);
709 }
710
711
712 /* useful */
713 /* gprs_access_point */
_gprs_access_point(GPRS * gprs)714 static int _gprs_access_point(GPRS * gprs)
715 {
716 int ret = 0;
717 PhonePluginHelper * helper = gprs->helper;
718 char const * p;
719 ModemRequest request;
720
721 if((p = helper->config_get(helper->phone, "gprs", "apn")) == NULL)
722 return 0;
723 memset(&request, 0, sizeof(request));
724 request.type = MODEM_REQUEST_AUTHENTICATE;
725 /* set the access point */
726 request.authenticate.name = "APN";
727 request.authenticate.username = "IP";
728 request.authenticate.password = p;
729 ret |= helper->request(helper->phone, &request);
730 /* set the credentials */
731 request.authenticate.name = "GPRS";
732 p = helper->config_get(helper->phone, "gprs", "username");
733 request.authenticate.username = p;
734 p = helper->config_get(helper->phone, "gprs", "password");
735 request.authenticate.password = p;
736 ret |= helper->request(helper->phone, &request);
737 return ret;
738 }
739
740
741 /* gprs_connect */
_gprs_connect(GPRS * gprs)742 static int _gprs_connect(GPRS * gprs)
743 {
744 GtkDialogFlags flags = GTK_DIALOG_MODAL
745 | GTK_DIALOG_DESTROY_WITH_PARENT;
746 char const message[] = "You are currently roaming, and additional"
747 " charges are therefore likely to apply.\n"
748 "Do you really want to connect?";
749 GtkWidget * widget;
750 int res;
751 ModemRequest request;
752
753 if(_gprs_access_point(gprs) != 0)
754 return -1;
755 if(gprs->roaming)
756 {
757 widget = gtk_message_dialog_new(GTK_WINDOW(gprs->window), flags,
758 GTK_MESSAGE_WARNING, GTK_BUTTONS_YES_NO,
759 #if GTK_CHECK_VERSION(2, 6, 0)
760 "%s", "Warning");
761 gtk_message_dialog_format_secondary_text(GTK_MESSAGE_DIALOG(
762 widget),
763 #endif
764 "%s", message);
765 gtk_window_set_title(GTK_WINDOW(widget), "Warning");
766 res = gtk_dialog_run(GTK_DIALOG(widget));
767 gtk_widget_destroy(widget);
768 if(res != GTK_RESPONSE_YES)
769 return 0;
770 }
771 _gprs_set_connected(gprs, TRUE, "Connecting...", 0, 0);
772 memset(&request, 0, sizeof(request));
773 request.type = MODEM_REQUEST_CALL;
774 request.call.call_type = MODEM_CALL_TYPE_DATA;
775 request.call.number = "*99***1#"; /* XXX specific to GSM/GPRS */
776 if(gprs->helper->request(gprs->helper->phone, &request) != 0)
777 return -gprs->helper->error(gprs->helper->phone,
778 error_get(NULL), 1);
779 return 0;
780 }
781
782
783 /* gprs_counters_load */
_gprs_counters_load(GPRS * gprs)784 static void _gprs_counters_load(GPRS * gprs)
785 {
786 PhonePluginHelper * helper = gprs->helper;
787 char const * p;
788
789 gprs->glin = 0;
790 if((p = helper->config_get(helper->phone, "gprs", "in")) != NULL)
791 gprs->glin = strtol(p, NULL, 10);
792 gprs->glout = 0;
793 if((p = helper->config_get(helper->phone, "gprs", "out")) != NULL)
794 gprs->glout = strtol(p, NULL, 10);
795 }
796
797
798 /* gprs_counters_save */
_gprs_counters_save(GPRS * gprs)799 static void _gprs_counters_save(GPRS * gprs)
800 {
801 PhonePluginHelper * helper = gprs->helper;
802 char buf[16];
803
804 snprintf(buf, sizeof(buf), "%lu", gprs->glin);
805 helper->config_set(helper->phone, "gprs", "in", buf);
806 snprintf(buf, sizeof(buf), "%lu", gprs->glout);
807 helper->config_set(helper->phone, "gprs", "out", buf);
808 }
809
810
811 /* gprs_disconnect */
_gprs_disconnect(GPRS * gprs)812 static int _gprs_disconnect(GPRS * gprs)
813 {
814 ModemRequest request;
815
816 if(_gprs_access_point(gprs) != 0)
817 return -1;
818 _gprs_set_connected(gprs, TRUE, "Disconnecting...", 0, 0);
819 memset(&request, 0, sizeof(request));
820 request.type = MODEM_REQUEST_CALL_HANGUP;
821 return gprs->helper->request(gprs->helper->phone, &request);
822 }
823
824
825 /* gprs_load_defaults */
_gprs_load_defaults(GPRS * gprs)826 static int _gprs_load_defaults(GPRS * gprs)
827 {
828 return _gprs_load_operator(gprs, gprs->_operator);
829 }
830
831
832 /* gprs_load_operator */
_gprs_load_operator(GPRS * gprs,char const * _operator)833 static int _gprs_load_operator(GPRS * gprs, char const * _operator)
834 {
835 Config * config;
836 String const * p;
837
838 if((config = config_new()) == NULL)
839 return -1;
840 if(config_load(config, SYSCONFDIR "/" PACKAGE "/gprs.conf") != 0
841 || (p = config_get(config, _operator, "apn")) == NULL)
842 {
843 config_delete(config);
844 return -1;
845 }
846 gtk_entry_set_text(GTK_ENTRY(gprs->apn), p);
847 if((p = config_get(config, _operator, "username")) == NULL)
848 p = "";
849 gtk_entry_set_text(GTK_ENTRY(gprs->username), p);
850 if((p = config_get(config, _operator, "password")) == NULL)
851 p = "";
852 gtk_entry_set_text(GTK_ENTRY(gprs->password), p);
853 config_delete(config);
854 return 0;
855 }
856
857
858 /* callbacks */
859 /* gprs_on_activate */
_gprs_on_activate(gpointer data)860 static void _gprs_on_activate(gpointer data)
861 {
862 GPRS * gprs = data;
863
864 _gprs_settings(gprs);
865 gtk_notebook_set_current_page(GTK_NOTEBOOK(gprs->notebook), 1);
866 gtk_window_present(GTK_WINDOW(gprs->window));
867 }
868
869
870 /* gprs_on_load_defaults */
_gprs_on_load_defaults(gpointer data)871 static void _gprs_on_load_defaults(gpointer data)
872 {
873 GPRS * gprs = data;
874 GtkWidget * widget;
875 const GtkDialogFlags flags = GTK_DIALOG_MODAL
876 | GTK_DIALOG_DESTROY_WITH_PARENT;
877
878 if(_gprs_load_defaults(gprs) == 0)
879 return;
880 widget = gtk_message_dialog_new(GTK_WINDOW(gprs->window),
881 flags, GTK_MESSAGE_ERROR, GTK_BUTTONS_CLOSE,
882 #if GTK_CHECK_VERSION(2, 6, 0)
883 "%s", "Error");
884 gtk_message_dialog_format_secondary_text(GTK_MESSAGE_DIALOG(
885 widget),
886 #endif
887 "%s", "No defaults known for the current operator");
888 gtk_dialog_run(GTK_DIALOG(widget));
889 gtk_widget_destroy(widget);
890 }
891
892
893 /* gprs_on_popup_menu */
_gprs_on_popup_menu(GtkStatusIcon * icon,guint button,guint time,gpointer data)894 static void _gprs_on_popup_menu(GtkStatusIcon * icon, guint button,
895 guint time, gpointer data)
896 {
897 GPRS * gprs = data;
898 GtkWidget * menu;
899 GtkWidget * menuitem;
900 GtkWidget * image;
901
902 menu = gtk_menu_new();
903 /* status */
904 menuitem = gtk_image_menu_item_new_with_mnemonic("_Status");
905 g_signal_connect_swapped(menuitem, "activate", G_CALLBACK(
906 _gprs_on_activate), gprs);
907 gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem);
908 menuitem = gtk_separator_menu_item_new();
909 gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem);
910 /* connection */
911 menuitem = gtk_image_menu_item_new_with_mnemonic(gprs->connected
912 ? "_Disconnect" : "_Connect");
913 image = gtk_image_new_from_stock(gprs->connected ? GTK_STOCK_DISCONNECT
914 : GTK_STOCK_CONNECT, GTK_ICON_SIZE_MENU);
915 gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(menuitem), image);
916 g_signal_connect_swapped(menuitem, "activate", G_CALLBACK(
917 gprs->connected ? _gprs_disconnect
918 : _gprs_connect), gprs);
919 gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem);
920 menuitem = gtk_separator_menu_item_new();
921 gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem);
922 /* preferences */
923 menuitem = gtk_image_menu_item_new_from_stock(GTK_STOCK_PREFERENCES,
924 NULL);
925 g_signal_connect_swapped(menuitem, "activate", G_CALLBACK(
926 _gprs_settings), gprs);
927 gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem);
928 #ifdef PROGNAME
929 menuitem = gtk_separator_menu_item_new();
930 gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem);
931 /* quit */
932 menuitem = gtk_image_menu_item_new_from_stock(GTK_STOCK_QUIT, NULL);
933 g_signal_connect(menuitem, "activate", G_CALLBACK(gtk_main_quit), NULL);
934 gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem);
935 #endif
936 gtk_widget_show_all(menu);
937 gtk_menu_popup(GTK_MENU(menu), NULL, NULL, NULL, NULL, button, time);
938 }
939
940
941 /* gprs_on_timeout */
_gprs_on_timeout(gpointer data)942 static gboolean _gprs_on_timeout(gpointer data)
943 {
944 GPRS * gprs = data;
945
946 gprs->helper->trigger(gprs->helper->phone, MODEM_EVENT_TYPE_CONNECTION);
947 return TRUE;
948 }
949