Use a configuration file for USSD codes

This commit is contained in:
Pierre Pronchery 2018-12-29 00:01:27 +01:00
parent 381ef28be5
commit 07c79f1fc0
3 changed files with 169 additions and 505 deletions

View File

@ -146,7 +146,7 @@ sources=ussd.c
install=$(LIBDIR)/Phone/plugins install=$(LIBDIR)/Phone/plugins
[ussd.c] [ussd.c]
depends=../../include/Phone.h depends=../../include/Phone.h,../../config.h
[video] [video]
type=plugin type=plugin

View File

@ -12,11 +12,10 @@
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. */ * along with this program. If not, see <http://www.gnu.org/licenses/>. */
/* FIXME:
* - use a configuration file instead */
#include <stdlib.h>
#ifdef DEBUG #ifdef DEBUG
# include <stdio.h> # include <stdio.h>
#endif #endif
@ -24,6 +23,14 @@
#include <gtk/gtk.h> #include <gtk/gtk.h>
#include <System.h> #include <System.h>
#include "Phone.h" #include "Phone.h"
#include "../../config.h"
#ifndef PREFIX
# define PREFIX "/usr/local"
#endif
#ifndef SYSCONFDIR
# define SYSCONFDIR PREFIX "/etc"
#endif
/* USSD */ /* USSD */
@ -32,103 +39,29 @@
typedef struct _PhonePlugin typedef struct _PhonePlugin
{ {
PhonePluginHelper * helper; PhonePluginHelper * helper;
size_t _operator; Config * config;
char * _operator;
/* widgets */ /* widgets */
GtkWidget * window; GtkWidget * window;
GtkWidget * operators; GtkWidget * operators;
GtkWidget * codes; GtkWidget * codes;
} USSD; } USSD;
typedef struct _USSDCode typedef enum _USSDOperator
{ {
char const * number; UO_OPERATOR = 0,
char const * name; UO_DISPLAY
} USSDOperator;
#define UO_LAST UO_DISPLAY
#define UO_COUNT (UO_LAST + 1)
typedef enum _USSDCode
{
UC_CODE = 0,
UC_DISPLAY
} USSDCode; } USSDCode;
#define UC_LAST UC_DISPLAY
#define UC_COUNT (UC_LAST + 1)
/* constants */
/* Germany */
static USSDCode _ussd_codes_de_ccc_32c3[] =
{
{ "*#100#", "Number request" },
{ NULL, NULL }
};
/* E-Plus, see http://www.prepaid-wiki.de/index.php5/E-Plus */
static USSDCode _ussd_codes_de_eplus[] =
{
{ "*100#", "Balance enquiry" },
{ NULL, NULL }
};
/* FYVE, see http://www.prepaid-wiki.de/index.php5/FYVE#Servicefunktionen */
static USSDCode _ussd_codes_de_fyve[] =
{
{ "*100#", "Balance enquiry and charging menu" },
{ "*106#", "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 }
};
/* Telekom */
static USSDCode _ussd_codes_de_telekom[] =
{
{ "*2221#", "Multi-SIM: current status" },
{ "*2222#", "Multi-SIM: set card as default" },
{ NULL, NULL }
};
/* Virgin Mobile, see
* http://fr.wikipedia.org/wiki/Unstructured_Supplementary_Service_Data */
static USSDCode _ussd_codes_fr_virgin[] =
{
{ "*144#", "Balance enquiry" },
{ NULL, NULL }
};
/* Vodafone India, see
* http://broadbandforum.in/vodafone-3g/66861-important-vodafone-sms-codes-ussd/
*/
static USSDCode _ussd_codes_in_vodafone[] =
{
{ "*141#", "Balance enquiry" },
{ "*444#", "Self-service portal" },
{ "*225*6#", "See unused GPRS data and expiry" },
{ "*225*3#", "See unused 3G data and expiry" },
{ "*444*5#", "Activate 30MB, 1 day, GPRS plan" },
{ NULL, NULL }
};
static const struct
{
char const * name;
char const * _operator;
USSDCode * codes;
} _ussd_operators[] =
{
/* FIXME obtain the corresponding operator names */
{ "CCC 32C3", NULL, _ussd_codes_de_ccc_32c3 },
{ "E-Plus", NULL, _ussd_codes_de_eplus },
{ "FYVE", NULL, _ussd_codes_de_fyve },
{ "Monacell", NULL, _ussd_codes_fr_virgin },
{ "MTN", NULL, _ussd_codes_za_mtn },
{ "NRJ", NULL, _ussd_codes_fr_virgin },
{ "Telekom", "Telekom.de", _ussd_codes_de_telekom },
{ "Virgin", NULL, _ussd_codes_fr_virgin },
{ "Vodafone", NULL, _ussd_codes_in_vodafone },
{ NULL, NULL, NULL }
};
/* prototypes */ /* prototypes */
@ -139,7 +72,7 @@ static int _ussd_event(USSD * ussd, PhoneEvent * event);
static void _ussd_settings(USSD * ussd); static void _ussd_settings(USSD * ussd);
/* useful */ /* useful */
static int _ussd_load_operator(USSD * ussd, char const * _operator); static int _ussd_load_operator(USSD * ussd, char const * name);
/* callbacks */ /* callbacks */
static void _ussd_on_operators_changed(gpointer data); static void _ussd_on_operators_changed(gpointer data);
@ -170,11 +103,16 @@ static USSD * _ussd_init(PhonePluginHelper * helper)
if((ussd = object_new(sizeof(*ussd))) == NULL) if((ussd = object_new(sizeof(*ussd))) == NULL)
return NULL; return NULL;
ussd->config = config_new();
ussd->_operator = NULL;
ussd->helper = helper; ussd->helper = helper;
ussd->_operator = 0;
ussd->window = NULL; ussd->window = NULL;
ussd->operators = NULL; ussd->operators = NULL;
ussd->codes = NULL; ussd->codes = NULL;
/* check for errors */
if(ussd->config == NULL || config_load(ussd->config,
SYSCONFDIR "/" PACKAGE "/ussd.conf") != 0)
helper->error(helper->phone, error_get(NULL), 1);
return ussd; return ussd;
} }
@ -184,6 +122,9 @@ static void _ussd_destroy(USSD * ussd)
{ {
if(ussd->window != NULL) if(ussd->window != NULL)
gtk_widget_destroy(ussd->window); gtk_widget_destroy(ussd->window);
free(ussd->_operator);
if(ussd->config != NULL)
config_delete(ussd->config);
object_delete(ussd); object_delete(ussd);
} }
@ -221,6 +162,7 @@ static int _event_modem(USSD * ussd, ModemEvent * event)
/* ussd_settings */ /* ussd_settings */
static void _settings_window(USSD * ussd); static void _settings_window(USSD * ussd);
static void _settings_window_operators(String const * section, void * data);
static void _ussd_settings(USSD * ussd) static void _ussd_settings(USSD * ussd)
{ {
@ -232,11 +174,12 @@ static void _ussd_settings(USSD * ussd)
static void _settings_window(USSD * ussd) static void _settings_window(USSD * ussd)
{ {
GtkSizeGroup * group; GtkSizeGroup * group;
GtkListStore * model;
GtkWidget * vbox; GtkWidget * vbox;
GtkWidget * hbox; GtkWidget * hbox;
GtkWidget * image; GtkWidget * image;
GtkWidget * widget; GtkWidget * widget;
size_t i; GtkCellRenderer * renderer;
group = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL); group = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
ussd->window = gtk_window_new(GTK_WINDOW_TOPLEVEL); ussd->window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
@ -267,17 +210,15 @@ static void _settings_window(USSD * ussd)
#endif #endif
gtk_size_group_add_widget(group, widget); gtk_size_group_add_widget(group, widget);
gtk_box_pack_start(GTK_BOX(hbox), widget, FALSE, TRUE, 0); gtk_box_pack_start(GTK_BOX(hbox), widget, FALSE, TRUE, 0);
#if GTK_CHECK_VERSION(3, 0, 0) model = gtk_list_store_new(UO_COUNT, G_TYPE_STRING, G_TYPE_STRING);
ussd->operators = gtk_combo_box_text_new(); ussd->operators = gtk_combo_box_new_with_model(GTK_TREE_MODEL(model));
for(i = 0; _ussd_operators[i].name != NULL; i++) renderer = gtk_cell_renderer_text_new();
gtk_combo_box_text_append(GTK_COMBO_BOX_TEXT(ussd->operators), gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(ussd->operators), renderer,
NULL, _ussd_operators[i].name); TRUE);
#else gtk_cell_layout_set_attributes(GTK_CELL_LAYOUT(ussd->operators),
ussd->operators = gtk_combo_box_new_text(); renderer, "text", UO_DISPLAY, NULL);
for(i = 0; _ussd_operators[i].name != NULL; i++) if(ussd->config != NULL)
gtk_combo_box_append_text(GTK_COMBO_BOX(ussd->operators), config_foreach(ussd->config, _settings_window_operators, ussd);
_ussd_operators[i].name);
#endif
g_signal_connect_swapped(ussd->operators, "changed", G_CALLBACK( g_signal_connect_swapped(ussd->operators, "changed", G_CALLBACK(
_ussd_on_operators_changed), ussd); _ussd_on_operators_changed), ussd);
gtk_box_pack_start(GTK_BOX(hbox), ussd->operators, TRUE, TRUE, 0); gtk_box_pack_start(GTK_BOX(hbox), ussd->operators, TRUE, TRUE, 0);
@ -296,11 +237,13 @@ static void _settings_window(USSD * ussd)
#endif #endif
gtk_size_group_add_widget(group, widget); gtk_size_group_add_widget(group, widget);
gtk_box_pack_start(GTK_BOX(hbox), widget, FALSE, TRUE, 0); gtk_box_pack_start(GTK_BOX(hbox), widget, FALSE, TRUE, 0);
#if GTK_CHECK_VERSION(3, 0, 0) model = gtk_list_store_new(UC_COUNT, G_TYPE_STRING, G_TYPE_STRING);
ussd->codes = gtk_combo_box_text_new(); ussd->codes = gtk_combo_box_new_with_model(GTK_TREE_MODEL(model));
#else renderer = gtk_cell_renderer_text_new();
ussd->codes = gtk_combo_box_new_text(); gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(ussd->codes), renderer,
#endif TRUE);
gtk_cell_layout_set_attributes(GTK_CELL_LAYOUT(ussd->codes), renderer,
"text", UC_DISPLAY, NULL);
gtk_box_pack_start(GTK_BOX(hbox), ussd->codes, TRUE, TRUE, 0); gtk_box_pack_start(GTK_BOX(hbox), ussd->codes, TRUE, TRUE, 0);
gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, TRUE, 0); gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, TRUE, 0);
/* send */ /* send */
@ -338,59 +281,98 @@ static void _settings_window(USSD * ussd)
gtk_container_add(GTK_CONTAINER(hbox), widget); gtk_container_add(GTK_CONTAINER(hbox), widget);
gtk_box_pack_end(GTK_BOX(vbox), hbox, FALSE, TRUE, 0); gtk_box_pack_end(GTK_BOX(vbox), hbox, FALSE, TRUE, 0);
gtk_container_add(GTK_CONTAINER(ussd->window), vbox); gtk_container_add(GTK_CONTAINER(ussd->window), vbox);
gtk_combo_box_set_active(GTK_COMBO_BOX(ussd->operators), gtk_combo_box_set_active(GTK_COMBO_BOX(ussd->operators), 0);
ussd->_operator);
gtk_widget_show_all(vbox); gtk_widget_show_all(vbox);
} }
static void _settings_window_operators(String const * section, void * data)
{
USSD * ussd = data;
GtkTreeModel * model;
GtkTreeIter iter;
String const * name;
model = gtk_combo_box_get_model(GTK_COMBO_BOX(ussd->operators));
gtk_list_store_append(GTK_LIST_STORE(model), &iter);
name = config_get(ussd->config, section, "name");
gtk_list_store_set(GTK_LIST_STORE(model), &iter, UO_OPERATOR, section,
UO_DISPLAY, (name != NULL) ? name : section, -1);
}
/* useful */ /* useful */
/* ussd_load_operator */ /* ussd_load_operator */
static int _ussd_load_operator(USSD * ussd, char const * _operator) static int _ussd_load_operator(USSD * ussd, char const * name)
{ {
size_t i; GtkTreeModel * model;
GtkTreeIter iter;
gboolean valid;
gchar * _operator;
if(_operator == NULL) if(name == NULL)
return -1; return -1;
for(i = 0; _ussd_operators[i].name != NULL; i++) free(ussd->_operator);
if(_ussd_operators[i]._operator == NULL) if((ussd->_operator = strdup(name)) == NULL)
continue; return -1;
else if(strcmp(_ussd_operators[i]._operator, _operator) == 0) model = gtk_combo_box_get_model(GTK_COMBO_BOX(ussd->operators));
for(valid = gtk_tree_model_get_iter_first(model, &iter); valid;
valid = gtk_tree_model_iter_next(model, &iter))
{
gtk_tree_model_get(model, &iter, UO_OPERATOR, &_operator, -1);
valid = (strcmp(name, _operator) == 0) ? TRUE : FALSE;
g_free(_operator);
if(valid)
{ {
ussd->_operator = i; gtk_combo_box_set_active_iter(
if(ussd->window != NULL) GTK_COMBO_BOX(ussd->operators), &iter);
gtk_combo_box_set_active(GTK_COMBO_BOX(
ussd->operators), i);
break; break;
} }
}
return 0; return 0;
} }
/* callbacks */ /* callbacks */
/* ussd_on_operators_changed */ /* ussd_on_operators_changed */
static void _ussd_on_operators_changed_operator(char const * variable,
char const * value, void * data);
static void _ussd_on_operators_changed(gpointer data) static void _ussd_on_operators_changed(gpointer data)
{ {
USSD * ussd = data; USSD * ussd = data;
GtkTreeModel * model; GtkTreeModel * model;
int i; GtkTreeIter iter;
USSDCode * codes; gchar * p;
model = gtk_combo_box_get_model(GTK_COMBO_BOX(ussd->codes)); model = gtk_combo_box_get_model(GTK_COMBO_BOX(ussd->codes));
gtk_list_store_clear(GTK_LIST_STORE(model)); gtk_list_store_clear(GTK_LIST_STORE(model));
i = gtk_combo_box_get_active(GTK_COMBO_BOX(ussd->operators)); if(gtk_combo_box_get_active_iter(GTK_COMBO_BOX(ussd->operators), &iter)
codes = _ussd_operators[i].codes; != TRUE)
for(i = 0; codes[i].name != NULL; i++) return;
#if GTK_CHECK_VERSION(3, 0, 0) model = gtk_combo_box_get_model(GTK_COMBO_BOX(ussd->operators));
gtk_combo_box_text_append(GTK_COMBO_BOX_TEXT(ussd->codes), gtk_tree_model_get(model, &iter, UO_OPERATOR, &p, -1);
NULL, codes[i].name); if(ussd->config != NULL)
#else config_foreach_section(ussd->config, p,
gtk_combo_box_append_text(GTK_COMBO_BOX(ussd->codes), _ussd_on_operators_changed_operator, ussd);
codes[i].name); g_free(p);
#endif
gtk_combo_box_set_active(GTK_COMBO_BOX(ussd->codes), 0); gtk_combo_box_set_active(GTK_COMBO_BOX(ussd->codes), 0);
} }
static void _ussd_on_operators_changed_operator(char const * variable,
char const * value, void * data)
{
USSD * ussd = data;
GtkTreeModel * model;
GtkTreeIter iter;
if(strcmp(variable, "name") == 0)
return;
model = gtk_combo_box_get_model(GTK_COMBO_BOX(ussd->codes));
gtk_list_store_append(GTK_LIST_STORE(model), &iter);
gtk_list_store_set(GTK_LIST_STORE(model), &iter, UC_CODE, variable,
UC_DISPLAY, value, -1);
}
/* ussd_on_settings_close */ /* ussd_on_settings_close */
static void _ussd_on_settings_close(gpointer data) static void _ussd_on_settings_close(gpointer data)
@ -406,19 +388,20 @@ static void _ussd_on_settings_send(gpointer data)
{ {
USSD * ussd = data; USSD * ussd = data;
PhonePluginHelper * helper = ussd->helper; PhonePluginHelper * helper = ussd->helper;
int i; GtkTreeModel * model;
USSDCode * codes; GtkTreeIter iter;
gchar * code;
ModemRequest request; ModemRequest request;
i = gtk_combo_box_get_active(GTK_COMBO_BOX(ussd->operators)); model = gtk_combo_box_get_model(GTK_COMBO_BOX(ussd->codes));
codes = _ussd_operators[i].codes; if(gtk_combo_box_get_active_iter(GTK_COMBO_BOX(ussd->codes), &iter)
i = gtk_combo_box_get_active(GTK_COMBO_BOX(ussd->codes)); != TRUE)
#ifdef DEBUG return;
fprintf(stderr, "DEBUG: %s() \"%s\"\n", __func__, codes[i].number); gtk_tree_model_get(model, &iter, UC_CODE, &code, -1);
#endif
memset(&request, 0, sizeof(request)); memset(&request, 0, sizeof(request));
request.type = MODEM_REQUEST_CALL; request.type = MODEM_REQUEST_CALL;
request.call.call_type = MODEM_CALL_TYPE_VOICE; request.call.call_type = MODEM_CALL_TYPE_VOICE;
request.call.number = codes[i].number; request.call.number = code;
helper->request(helper->phone, &request); helper->request(helper->phone, &request);
g_free(code);
} }

View File

@ -1,368 +1,49 @@
[du] [CCC 32C3]
msisdn-query=*#100# *#100#=Number request
[Karabakh Telecom]
balance-check=*122#
balance-top-up=*123*CODE#
[tele.ring]
balance-check=*102#
[Azerfon]
msisdn-query=*100#3#
[m:tel]
balance-check=*101#
[HT-ERONET]
balance-check=*101#
[Robi (AKTel)]
balance-check=*222#
balance-top-up=*111*CODE#
msisdn-query=*140*2*4#
[Banglalink]
balance-check=*124#
balance-top-up=*123*CODE#
msisdn-query=*511#
[GrameenPhone]
balance-check=*566#
balance-top-up=*555*CODE#
msisdn-query=*2#
[Airtel (Warid)]
balance-check=*778#
balance-top-up=*787*CODE#
msisdn-query=*121*6*3#
[Teletalk]
balance-check=*152#
balance-top-up=#151*CODE#
msisdn-query=*551#
[Mobistar]
balance-check=#123#
[GloBul]
balance-check=*125#
[M-Tel]
balance-check=*101#
[Vivacom]
balance-check=*102#
[Claro]
balance-check=*544#
[TIM]
balance-check=*222#
[velcom]
balance-check=*100#
[MTS]
balance-check=*100#
[life:)]
balance-check=*100#
[Orange]
balance-check=#121#
balance-top-up=#121*CODE#
[Swisscom]
balance-check=*130#
balance-top-up=*123*CODE#
[M-Budget]
msisdn-query=*#100#
[Cytamobile-Vodafone]
msisdn-query=*#109#
[Vodafone]
balance-check=*22#
[O2]
balance-check=*104*#
balance-top-up=*102*CODE#
[AldiTalk/MedionMobile]
balance-check=*100#
balance-top-up=*104*CODE#
[blau.de]
balance-check=*100#
balance-top-up=*104*CODE#
[E-Plus] [E-Plus]
balance-check=*100# #E-Plus, see
balance-top-up=*104*CODE# #http://www.prepaid-wiki.de/index.php5/E-Plus
*100#=Balance enquiry
[O2] [FYVE]
balance-check=*101# #FYVE, see
balance-top-up=*103*CODE# #http://www.prepaid-wiki.de/index.php5/FYVE#Servicefunktionen
*100#=Balance enquiry and charging menu
*106#=Balance enquiry
[Tchibo-Mobil] [Monacell]
balance-check=*101# #like Virgin
balance-top-up=*103*CODE# *144#=Balance enquiry
[T-Mobile(Telekom)]
balance-check=*100#
balance-top-up=*101*CODE#
[Congstar]
balance-check=*100#
balance-top-up=*101*CODE#
[Vodafone]
balance-check=*100#
balance-top-up=*100*CODE#
[FONIC]
balance-check=*101#
balance-top-up=*103*CODE#
[simyo Internet]
balance-check=*100#
balance-top-up=*104*CODE#
[1&1]
balance-check=*100#
[Telenor]
balance-check=*101#
[TDC]
balance-check=*101#
[Telia]
balance-check=*101#
[Orange]
balance-check=#131#
[Claro]
balance-check=*122#
[Viva]
balance-check=#111#
[Vodafone]
msisdn-query=*878#
[Orange]
balance-check=*111#
[Vodafone]
msisdn-query=*138#
[Yoigo]
balance-check=*111#
[Ethio Telecom]
balance-check=*804#
[Vodafone FO]
msisdn-query=*#100#
[Vodafone / Kidanet]
msisdn-query=*999#
[Orange]
balance-check=#123#
balance-top-up=#124*CODE#
[O2]
balance-check=*#10#
[giffgaff]
balance-check=*100#
[Vodafone]
balance-check=*#1345#
msisdn-query=*#100#
[MTN] [MTN]
balance-check=*124# #MTN, see
balance-top-up=*125*CODE# #http://www.mtn.co.za/Support/faq/Pages/USSD.aspx
*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
[NRJ]
#like Virgin
*144#=Balance enquiry
[Telekom.de]
*2221#=Multi-SIM: current status
*2222#=Multi-SIM: set card as default
[Virgin]
#Virgin Mobile, see
#http://fr.wikipedia.org/wiki/Unstructured_Supplementary_Service_Data
*144#=Balance enquiry
[Vodafone] [Vodafone]
balance-check=*122# #Vodafone India, see
balance-top-up=*123*CODE# #http://broadbandforum.in/vodafone-3g/66861-important-vodafone-sms-codes-ussd/
msisdn-query=*127# *141#=Balance enquiry
*444#=Self-service portal
[Tigo] *225*6#=See unused GPRS data and expiry
balance-check=*820# *225*3#=See unused 3G data and expiry
balance-top-up=*842*CODE# *444*5#=Activate 30MB, 1 day, GPRS plan
[Airtel]
balance-check=*133#
balance-top-up=*134*CODE#
[GloGhana]
balance-check=*124#
balance-top-up=*123*CODE#
[O2]
balance-check=*#100#
[Reliance]
balance-check= *111*1*3#
[Safaricom]
balance-check=*144#
balance-top-up=*544*CODE#
[Beeline]
balance-check=*102#
[MegaCom]
balance-check=*500#
[O!]
balance-check=*100#
[Cellcard]
balance-check=#124#
[Hello]
balance-check=*100#
[qb]
balance-check=#132#
[Smart Mobile]
balance-check=*888#
[Metfone]
balance-check=*097#
[Beeline]
balance-check=*102#
[Mfone]
balance-check=*222#
[Lao Telecom]
balance-check=*122#
[Airtel NG]
balance-check=*123#
balance-top-up=*126*CODE#
[MTN]
balance-check=*556#
balance-top-up=*555*CODE#
[Glo Mobile]
balance-check=#124#
balance-top-up=*123*CODE#
[Etisalat]
balance-check=*232#
balance-top-up=*222*CODE#
[Vodafone]
msisdn-query=*#100#
[Netcom]
balance-check=*150#
[Tele2]
balance-check=*111#
[T-mobile]
balance-check=*101#
balance-top-up=*111*CODE#
[Play Online]
balance-check=*101#
balance-top-up=*100*CODE#
[Orange]
balance-check=*124*#
balance-top-up=*125*CODE#
[Plus]
balance-check=*100#
balance-top-up=*123*CODE#
[Heyah]
balance-check=*108#
balance-top-up=*109*CODE#
[GaduAIR]
balance-check=*101#
[mBank mobile]
balance-check=*100#
[Vodafone]
msisdn-query=*#100#
[Beeline]
balance-check=*102#
[MTS]
balance-check=*100#
[Megafon]
balance-check=*100#
[U-tel]
balance-check=*100#
[Tele2]
balance-check=*111#
[Comviq]
balance-check=*111#
balance-top-up=*110*CODE#
[Telenor]
balance-check=*222#
[Telia]
balance-check=*120#
[Vodafone / Simobil]
msisdn-query=*100#
[Zain]
balance-check=*888#
balance-top-up=*888*CODE#
[Vodafone]
msisdn-query=*101#
[life:)]
balance-check=*111#
[Cell-c]
balance-check=*101#
balance-top-up=*102*CODE#
msisdn-query=*147*100#
[MTN]
balance-check=*141#
balance-top-up=*141*CODE#
msisdn-query=*123*888#
[Vodacom]
balance-check=*100#
balance-top-up=*100*01*CODE#
msisdn-query=*111*501#
[Virgin Mobile]
balance-check=*101#
balance-top-up=*102*CODE#
[8.ta]
balance-check=*188#
balance-top-up=*188*CODE#
msisdn-query=*1#