From bc91219ec811f92c8f46f04e3ade7e6e24528d58 Mon Sep 17 00:00:00 2001 From: Pierre Pronchery Date: Sat, 10 Dec 2011 23:03:28 +0000 Subject: [PATCH] Introducing the USSD plug-in --- Makefile | 1 + src/plugins/Makefile | 19 ++- src/plugins/project.conf | 10 +- src/plugins/ussd.c | 272 +++++++++++++++++++++++++++++++++++++++ 4 files changed, 298 insertions(+), 4 deletions(-) create mode 100644 src/plugins/ussd.c diff --git a/Makefile b/Makefile index af616e4..9a681be 100644 --- a/Makefile +++ b/Makefile @@ -102,6 +102,7 @@ dist: $(PACKAGE)-$(VERSION)/src/plugins/profiles.c \ $(PACKAGE)-$(VERSION)/src/plugins/smscrypt.c \ $(PACKAGE)-$(VERSION)/src/plugins/systray.c \ + $(PACKAGE)-$(VERSION)/src/plugins/ussd.c \ $(PACKAGE)-$(VERSION)/src/plugins/Makefile \ $(PACKAGE)-$(VERSION)/src/plugins/project.conf \ $(PACKAGE)-$(VERSION)/src/plugins/16x16/Makefile \ diff --git a/src/plugins/Makefile b/src/plugins/Makefile index b461ea2..1c347f0 100644 --- a/src/plugins/Makefile +++ b/src/plugins/Makefile @@ -1,5 +1,5 @@ SUBDIRS = 16x16 24x24 32x32 48x48 -TARGETS = blacklist.so debug.so engineering.so gprs.so locker.so n900.so openmoko.so oss.so panel.so profiles.so smscrypt.so systray.so +TARGETS = blacklist.so debug.so engineering.so gprs.so locker.so n900.so openmoko.so oss.so panel.so profiles.so smscrypt.so systray.so ussd.so PREFIX = /usr/local DESTDIR = LIBDIR = $(PREFIX)/lib @@ -106,6 +106,13 @@ systray_LDFLAGS = $(LDFLAGSF) $(LDFLAGS) systray.so: $(systray_OBJS) $(CCSHARED) -o systray.so $(systray_OBJS) $(systray_LDFLAGS) +ussd_OBJS = ussd.o +ussd_CFLAGS = $(CPPFLAGSF) $(CPPFLAGS) $(CFLAGSF) $(CFLAGS) +ussd_LDFLAGS = $(LDFLAGSF) $(LDFLAGS) + +ussd.so: $(ussd_OBJS) + $(CCSHARED) -o ussd.so $(ussd_OBJS) $(ussd_LDFLAGS) + blacklist.o: blacklist.c ../../include/Phone.h $(CC) $(blacklist_CFLAGS) -c blacklist.c @@ -142,13 +149,16 @@ smscrypt.o: smscrypt.c ../../include/Phone.h systray.o: systray.c ../../include/Phone.h ../../config.h $(CC) $(systray_CFLAGS) -c systray.c +ussd.o: ussd.c ../../include/Phone.h + $(CC) $(ussd_CFLAGS) -c ussd.c + clean: @for i in $(SUBDIRS); do (cd $$i && $(MAKE) clean) || exit; done - $(RM) -- $(blacklist_OBJS) $(debug_OBJS) $(engineering_OBJS) $(gprs_OBJS) $(locker_OBJS) $(n900_OBJS) $(openmoko_OBJS) $(oss_OBJS) $(panel_OBJS) $(profiles_OBJS) $(smscrypt_OBJS) $(systray_OBJS) + $(RM) -- $(blacklist_OBJS) $(debug_OBJS) $(engineering_OBJS) $(gprs_OBJS) $(locker_OBJS) $(n900_OBJS) $(openmoko_OBJS) $(oss_OBJS) $(panel_OBJS) $(profiles_OBJS) $(smscrypt_OBJS) $(systray_OBJS) $(ussd_OBJS) distclean: @for i in $(SUBDIRS); do (cd $$i && $(MAKE) distclean) || exit; done - $(RM) -- $(blacklist_OBJS) $(debug_OBJS) $(engineering_OBJS) $(gprs_OBJS) $(locker_OBJS) $(n900_OBJS) $(openmoko_OBJS) $(oss_OBJS) $(panel_OBJS) $(profiles_OBJS) $(smscrypt_OBJS) $(systray_OBJS) + $(RM) -- $(blacklist_OBJS) $(debug_OBJS) $(engineering_OBJS) $(gprs_OBJS) $(locker_OBJS) $(n900_OBJS) $(openmoko_OBJS) $(oss_OBJS) $(panel_OBJS) $(profiles_OBJS) $(smscrypt_OBJS) $(systray_OBJS) $(ussd_OBJS) $(RM) -- $(TARGETS) install: $(TARGETS) @@ -177,6 +187,8 @@ install: $(TARGETS) $(INSTALL) -m 0644 -- smscrypt.so $(DESTDIR)$(LIBDIR)/Phone/plugins/smscrypt.so $(MKDIR) $(DESTDIR)$(LIBDIR)/Phone/plugins $(INSTALL) -m 0644 -- systray.so $(DESTDIR)$(LIBDIR)/Phone/plugins/systray.so + $(MKDIR) $(DESTDIR)$(LIBDIR)/Phone/plugins + $(INSTALL) -m 0644 -- ussd.so $(DESTDIR)$(LIBDIR)/Phone/plugins/ussd.so uninstall: @for i in $(SUBDIRS); do (cd $$i && $(MAKE) uninstall) || exit; done @@ -192,5 +204,6 @@ uninstall: $(RM) -- $(DESTDIR)$(LIBDIR)/Phone/plugins/profiles.so $(RM) -- $(DESTDIR)$(LIBDIR)/Phone/plugins/smscrypt.so $(RM) -- $(DESTDIR)$(LIBDIR)/Phone/plugins/systray.so + $(RM) -- $(DESTDIR)$(LIBDIR)/Phone/plugins/ussd.so .PHONY: all subdirs clean distclean install uninstall diff --git a/src/plugins/project.conf b/src/plugins/project.conf index f15ef3b..0a9d539 100644 --- a/src/plugins/project.conf +++ b/src/plugins/project.conf @@ -1,5 +1,5 @@ subdirs=16x16,24x24,32x32,48x48 -targets=blacklist,debug,engineering,gprs,locker,n900,openmoko,oss,panel,profiles,smscrypt,systray +targets=blacklist,debug,engineering,gprs,locker,n900,openmoko,oss,panel,profiles,smscrypt,systray,ussd cppflags_force=-I ../../include cppflags= cflags_force=-W `pkg-config --cflags libSystem gtk+-2.0` @@ -107,3 +107,11 @@ install=$(LIBDIR)/Phone/plugins [systray.c] depends=../../include/Phone.h,../../config.h + +[ussd] +type=plugin +sources=ussd.c +install=$(LIBDIR)/Phone/plugins + +[ussd.c] +depends=../../include/Phone.h diff --git a/src/plugins/ussd.c b/src/plugins/ussd.c new file mode 100644 index 0000000..3b1734d --- /dev/null +++ b/src/plugins/ussd.c @@ -0,0 +1,272 @@ +/* $Id$ */ +/* Copyright (c) 2011 Pierre Pronchery */ +/* This file is part of DeforaOS Desktop Phone */ +/* This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, version 3 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . */ + + + +#include +#include +#include +#include "Phone.h" + + +/* USSD */ +/* private */ +/* types */ +typedef struct _GPRS +{ + /* widgets */ + GtkWidget * window; + GtkWidget * operators; + GtkWidget * codes; +} USSD; + +typedef struct _USSDCode +{ + char const * number; + char const * name; +} USSDCode; + + +/* constants */ +/* Germany */ +/* E-plus, see http://www.prepaid-wiki.de/index.php5/E-Plus */ +static USSDCode _ussd_codes_de_eplus[] = +{ + { "*100#", "Balance enquiry" }, + { NULL, NULL } +}; + +/* MTN, see http://www.mtn.co.za/Support/faq/Pages/USSD.aspx */ +static USSDCode _ussd_codes_za_mtn[] = +{ + { "*141#", "Balance enquiry" }, + { "*141*4#", "Tariff Analyser and Priceplan Migrations menu" }, + { "*141*4*0#", "Tariff Analyser" }, + { "*141*6*0#", "Data bundle cancellation" }, + { "*141*7*0#", "SMS bundle cancellation" }, + { "*141*8#", "Yello Fortune Entries" }, + { NULL, NULL } +}; + +static const struct +{ + char const * name; + USSDCode * codes; +} _ussd_operators[] = +{ + { "E-plus", _ussd_codes_de_eplus }, + { "MTN", _ussd_codes_za_mtn }, + { NULL, NULL } +}; + + +/* prototypes */ +/* plugins */ +static int _ussd_init(PhonePlugin * plugin); +static void _ussd_destroy(PhonePlugin * plugin); +static int _ussd_event(PhonePlugin * plugin, PhoneEvent * event); +static void _ussd_settings(PhonePlugin * plugin); + +/* callbacks */ +static void _ussd_on_operators_changed(gpointer data); +static void _ussd_on_settings_close(gpointer data); +static void _ussd_on_settings_send(gpointer data); + + +/* public */ +/* variables */ +PhonePlugin plugin = +{ + NULL, + "USSD", + NULL, + _ussd_init, + _ussd_destroy, + _ussd_event, + _ussd_settings, + NULL +}; + + +/* private */ +/* functions */ +/* ussd_init */ +static int _ussd_init(PhonePlugin * plugin) +{ + USSD * ussd; + + if((ussd = object_new(sizeof(*ussd))) == NULL) + return -1; + plugin->priv = ussd; + ussd->window = NULL; + ussd->operators = NULL; + ussd->codes = NULL; + return 0; +} + + +/* ussd_destroy */ +static void _ussd_destroy(PhonePlugin * plugin) +{ + USSD * ussd = plugin->priv; + + if(ussd->window != NULL) + gtk_widget_destroy(ussd->window); + object_delete(ussd); +} + + +/* ussd_event */ +static int _ussd_event(PhonePlugin * plugin, PhoneEvent * event) +{ + return 0; +} + + +/* ussd_settings */ +static void _settings_window(PhonePlugin * plugin); + +static void _ussd_settings(PhonePlugin * plugin) +{ + USSD * ussd = plugin->priv; + + if(ussd->window == NULL) + _settings_window(plugin); + gtk_window_present(GTK_WINDOW(ussd->window)); +} + +static void _settings_window(PhonePlugin * plugin) +{ + USSD * ussd = plugin->priv; + GtkSizeGroup * group; + GtkWidget * vbox; + GtkWidget * hbox; + GtkWidget * image; + GtkWidget * widget; + size_t i; + + group = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL); + ussd->window = gtk_window_new(GTK_WINDOW_TOPLEVEL); + gtk_container_set_border_width(GTK_CONTAINER(ussd->window), 4); + gtk_window_set_default_size(GTK_WINDOW(ussd->window), 200, 300); +#if GTK_CHECK_VERSION(2, 6, 0) + gtk_window_set_icon_name(GTK_WINDOW(ussd->window), "gnome-settings"); +#endif + gtk_window_set_title(GTK_WINDOW(ussd->window), "USSD"); + g_signal_connect(ussd->window, "delete-event", G_CALLBACK( + gtk_widget_hide), NULL); + vbox = gtk_vbox_new(FALSE, 4); + /* operators */ + hbox = gtk_hbox_new(FALSE, 4); + widget = gtk_label_new("Operator:"); + gtk_misc_set_alignment(GTK_MISC(widget), 0.0, 0.5); + gtk_size_group_add_widget(group, widget); + gtk_box_pack_start(GTK_BOX(hbox), widget, FALSE, TRUE, 0); + ussd->operators = gtk_combo_box_new_text(); + for(i = 0; _ussd_operators[i].name != NULL; i++) + gtk_combo_box_append_text(GTK_COMBO_BOX(ussd->operators), + _ussd_operators[i].name); + g_signal_connect_swapped(ussd->operators, "changed", G_CALLBACK( + _ussd_on_operators_changed), ussd); + gtk_box_pack_start(GTK_BOX(hbox), ussd->operators, TRUE, TRUE, 0); + gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, TRUE, 0); + /* codes */ + hbox = gtk_hbox_new(FALSE, 4); + widget = gtk_label_new("Code:"); + gtk_misc_set_alignment(GTK_MISC(widget), 0.0, 0.5); + gtk_size_group_add_widget(group, widget); + gtk_box_pack_start(GTK_BOX(hbox), widget, FALSE, TRUE, 0); + ussd->codes = gtk_combo_box_new_text(); + gtk_box_pack_start(GTK_BOX(hbox), ussd->codes, TRUE, TRUE, 0); + gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, TRUE, 0); + /* send */ + hbox = gtk_hbox_new(FALSE, 4); + widget = gtk_label_new(NULL); + gtk_misc_set_alignment(GTK_MISC(widget), 0.0, 0.5); + gtk_size_group_add_widget(group, widget); + gtk_box_pack_start(GTK_BOX(hbox), widget, FALSE, TRUE, 0); + widget = gtk_button_new_with_label("Send request"); + image = gtk_image_new_from_icon_name("mail-send", GTK_ICON_SIZE_BUTTON); + gtk_button_set_image(GTK_BUTTON(widget), image); + g_signal_connect_swapped(widget, "clicked", G_CALLBACK( + _ussd_on_settings_send), plugin); + gtk_box_pack_start(GTK_BOX(hbox), widget, TRUE, TRUE, 0); + gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, TRUE, 0); + /* button box */ + hbox = gtk_hbutton_box_new(); + gtk_button_box_set_layout(GTK_BUTTON_BOX(hbox), GTK_BUTTONBOX_END); + gtk_button_box_set_spacing(GTK_BUTTON_BOX(hbox), 4); + widget = gtk_button_new_from_stock(GTK_STOCK_CLOSE); + g_signal_connect_swapped(widget, "clicked", G_CALLBACK( + _ussd_on_settings_close), ussd); + gtk_container_add(GTK_CONTAINER(hbox), widget); + gtk_box_pack_end(GTK_BOX(vbox), hbox, FALSE, TRUE, 0); + gtk_container_add(GTK_CONTAINER(ussd->window), vbox); + gtk_combo_box_set_active(GTK_COMBO_BOX(ussd->operators), 0); + gtk_widget_show_all(vbox); +} + + +/* callbacks */ +/* ussd_on_operators_changed */ +static void _ussd_on_operators_changed(gpointer data) +{ + USSD * ussd = data; + GtkTreeModel * model; + int i; + USSDCode * codes; + + model = gtk_combo_box_get_model(GTK_COMBO_BOX(ussd->codes)); + gtk_list_store_clear(GTK_LIST_STORE(model)); + i = gtk_combo_box_get_active(GTK_COMBO_BOX(ussd->operators)); + codes = _ussd_operators[i].codes; + for(i = 0; codes[i].name != NULL; i++) + gtk_combo_box_append_text(GTK_COMBO_BOX(ussd->codes), + codes[i].name); + gtk_combo_box_set_active(GTK_COMBO_BOX(ussd->codes), 0); +} + + +/* ussd_on_settings_close */ +static void _ussd_on_settings_close(gpointer data) +{ + USSD * ussd = data; + + gtk_widget_hide(ussd->window); +} + + +/* ussd_on_settings_send */ +static void _ussd_on_settings_send(gpointer data) +{ + PhonePlugin * plugin = data; + PhonePluginHelper * helper = plugin->helper; + USSD * ussd = plugin->priv; + int i; + USSDCode * codes; + ModemRequest request; + + i = gtk_combo_box_get_active(GTK_COMBO_BOX(ussd->operators)); + codes = _ussd_operators[i].codes; + i = gtk_combo_box_get_active(GTK_COMBO_BOX(ussd->codes)); +#ifdef DEBUG + fprintf(stderr, "DEBUG: %s() \"%s\"\n", __func__, codes[i].number); +#endif + memset(&request, 0, sizeof(request)); + request.type = MODEM_REQUEST_CALL; + request.call.call_type = MODEM_CALL_TYPE_DATA; + request.call.number = codes[i].number; + helper->request(helper->phone, &request); +}