mobile-providers: use libnm-gtk to work with mobile providers
This commit removes all the code in charge of playing with the database of mobile providers, which was originally included in order to perform MCCMNC->OperatorName and SID->OperatorName conversions. This logic is now exposed by libnm-gtk. https://bugzilla.gnome.org/show_bug.cgi?id=688943
This commit is contained in:
@@ -115,7 +115,6 @@ shell_public_headers_h = \
|
||||
shell-global.h \
|
||||
shell-invert-lightness-effect.h \
|
||||
shell-keybinding-modes.h \
|
||||
shell-mobile-providers.h \
|
||||
shell-mount-operation.h \
|
||||
shell-network-agent.h \
|
||||
shell-perf-log.h \
|
||||
@@ -160,7 +159,6 @@ libgnome_shell_la_SOURCES = \
|
||||
shell-invert-lightness-effect.c \
|
||||
shell-keyring-prompt.h \
|
||||
shell-keyring-prompt.c \
|
||||
shell-mobile-providers.c \
|
||||
shell-mount-operation.c \
|
||||
shell-network-agent.c \
|
||||
shell-perf-log.c \
|
||||
|
@@ -1,914 +0,0 @@
|
||||
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
* Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Copyright (C) 2009 Novell, Inc.
|
||||
* Author: Tambet Ingo (tambet@gmail.com).
|
||||
*
|
||||
* Copyright (C) 2009 - 2010 Red Hat, Inc.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <glib/gi18n.h>
|
||||
|
||||
#include "shell-mobile-providers.h"
|
||||
|
||||
#ifndef MOBILE_BROADBAND_PROVIDER_INFO
|
||||
#define MOBILE_BROADBAND_PROVIDER_INFO DATADIR "/mobile-broadband-provider-info/serviceproviders.xml"
|
||||
#endif
|
||||
|
||||
#define ISO_3166_COUNTRY_CODES DATADIR "/zoneinfo/iso3166.tab"
|
||||
|
||||
static ShellCountryMobileProvider *country_mobile_provider_new (const char *country_code,
|
||||
const gchar *country_name);
|
||||
|
||||
static GHashTable *
|
||||
read_country_codes (const gchar *country_codes)
|
||||
{
|
||||
GHashTable *table;
|
||||
GIOChannel *channel;
|
||||
GString *buffer;
|
||||
GError *error = NULL;
|
||||
GIOStatus status;
|
||||
|
||||
channel = g_io_channel_new_file (country_codes, "r", &error);
|
||||
if (!channel) {
|
||||
if (error) {
|
||||
g_warning ("Could not read %s: %s", country_codes, error->message);
|
||||
g_error_free (error);
|
||||
} else
|
||||
g_warning ("Could not read %s: Unknown error", country_codes);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
table = g_hash_table_new_full (g_str_hash,
|
||||
g_str_equal,
|
||||
g_free,
|
||||
(GDestroyNotify)shell_country_mobile_provider_unref);
|
||||
buffer = g_string_sized_new (32);
|
||||
|
||||
status = G_IO_STATUS_NORMAL;
|
||||
while (status == G_IO_STATUS_NORMAL) {
|
||||
status = g_io_channel_read_line_string (channel, buffer, NULL, &error);
|
||||
|
||||
switch (status) {
|
||||
case G_IO_STATUS_NORMAL:
|
||||
if (buffer->str[0] != '#') {
|
||||
ShellCountryMobileProvider *country_provider;
|
||||
char **pieces;
|
||||
|
||||
pieces = g_strsplit (buffer->str, "\t", 2);
|
||||
|
||||
/* Hack for rh#556292; iso3166.tab is just wrong */
|
||||
pieces[1] = pieces[1] ? g_strchomp (pieces[1]) : NULL;
|
||||
if (pieces[1] && !strcmp (pieces[1], "Britain (UK)")) {
|
||||
g_free (pieces[1]);
|
||||
pieces[1] = g_strdup (_("United Kingdom"));
|
||||
}
|
||||
|
||||
country_provider = country_mobile_provider_new (pieces[0], pieces[1]);
|
||||
g_hash_table_insert (table, pieces[0], country_provider);
|
||||
g_free (pieces);
|
||||
}
|
||||
|
||||
g_string_truncate (buffer, 0);
|
||||
break;
|
||||
case G_IO_STATUS_EOF:
|
||||
break;
|
||||
case G_IO_STATUS_ERROR:
|
||||
g_warning ("Error while reading: %s", error->message);
|
||||
g_error_free (error);
|
||||
break;
|
||||
case G_IO_STATUS_AGAIN:
|
||||
/* FIXME: Try again a few times, but really, it never happes, right? */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
g_string_free (buffer, TRUE);
|
||||
g_io_channel_unref (channel);
|
||||
|
||||
return table;
|
||||
}
|
||||
|
||||
/* XML Parser */
|
||||
|
||||
typedef enum {
|
||||
PARSER_TOPLEVEL = 0,
|
||||
PARSER_COUNTRY,
|
||||
PARSER_PROVIDER,
|
||||
PARSER_METHOD_GSM,
|
||||
PARSER_METHOD_GSM_APN,
|
||||
PARSER_METHOD_CDMA,
|
||||
PARSER_ERROR
|
||||
} MobileContextState;
|
||||
|
||||
typedef struct {
|
||||
GHashTable *table;
|
||||
|
||||
char *current_country;
|
||||
GSList *current_providers;
|
||||
ShellMobileProvider *current_provider;
|
||||
ShellMobileAccessMethod *current_method;
|
||||
|
||||
char *text_buffer;
|
||||
MobileContextState state;
|
||||
} MobileParser;
|
||||
|
||||
static ShellGsmMccMnc *
|
||||
mcc_mnc_new (const char *mcc, const char *mnc)
|
||||
{
|
||||
ShellGsmMccMnc *m;
|
||||
|
||||
m = g_slice_new (ShellGsmMccMnc);
|
||||
m->mcc = g_strstrip (g_strdup (mcc));
|
||||
m->mnc = g_strstrip (g_strdup (mnc));
|
||||
return m;
|
||||
}
|
||||
|
||||
/* added in porting */
|
||||
static ShellGsmMccMnc *
|
||||
mcc_mnc_copy (const ShellGsmMccMnc *other) {
|
||||
ShellGsmMccMnc *ret;
|
||||
|
||||
ret = g_slice_new (ShellGsmMccMnc);
|
||||
ret->mcc = g_strdup (other->mcc);
|
||||
ret->mnc = g_strdup (other->mnc);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void
|
||||
mcc_mnc_free (ShellGsmMccMnc *m)
|
||||
{
|
||||
g_return_if_fail (m != NULL);
|
||||
g_free (m->mcc);
|
||||
g_free (m->mnc);
|
||||
g_slice_free (ShellGsmMccMnc, m);
|
||||
}
|
||||
|
||||
/* added in porting */
|
||||
G_DEFINE_BOXED_TYPE (ShellGsmMccMnc, shell_gsm_mcc_mnc, mcc_mnc_copy, mcc_mnc_free)
|
||||
|
||||
static ShellMobileAccessMethod *
|
||||
access_method_new (void)
|
||||
{
|
||||
ShellMobileAccessMethod *method;
|
||||
|
||||
method = g_slice_new0 (ShellMobileAccessMethod);
|
||||
method->refs = 1;
|
||||
method->lcl_names = g_hash_table_new_full (g_str_hash, g_str_equal,
|
||||
(GDestroyNotify) g_free,
|
||||
(GDestroyNotify) g_free);
|
||||
|
||||
return method;
|
||||
}
|
||||
|
||||
ShellMobileAccessMethod *
|
||||
shell_mobile_access_method_ref (ShellMobileAccessMethod *method)
|
||||
{
|
||||
g_return_val_if_fail (method != NULL, NULL);
|
||||
g_return_val_if_fail (method->refs > 0, NULL);
|
||||
|
||||
method->refs++;
|
||||
|
||||
return method;
|
||||
}
|
||||
|
||||
void
|
||||
shell_mobile_access_method_unref (ShellMobileAccessMethod *method)
|
||||
{
|
||||
g_return_if_fail (method != NULL);
|
||||
g_return_if_fail (method->refs > 0);
|
||||
|
||||
if (--method->refs == 0) {
|
||||
g_free (method->name);
|
||||
g_hash_table_destroy (method->lcl_names);
|
||||
g_free (method->username);
|
||||
g_free (method->password);
|
||||
g_free (method->gateway);
|
||||
g_free (method->gsm_apn);
|
||||
g_slist_foreach (method->dns, (GFunc) g_free, NULL);
|
||||
g_slist_free (method->dns);
|
||||
|
||||
g_slice_free (ShellMobileAccessMethod, method);
|
||||
}
|
||||
}
|
||||
|
||||
GType
|
||||
shell_mobile_access_method_get_type (void)
|
||||
{
|
||||
static GType type = 0;
|
||||
|
||||
if (G_UNLIKELY (type == 0)) {
|
||||
type = g_boxed_type_register_static ("ShellMobileAccessMethod",
|
||||
(GBoxedCopyFunc) shell_mobile_access_method_ref,
|
||||
(GBoxedFreeFunc) shell_mobile_access_method_unref);
|
||||
}
|
||||
return type;
|
||||
}
|
||||
|
||||
|
||||
static ShellMobileProvider *
|
||||
provider_new (void)
|
||||
{
|
||||
ShellMobileProvider *provider;
|
||||
|
||||
provider = g_slice_new0 (ShellMobileProvider);
|
||||
provider->refs = 1;
|
||||
provider->lcl_names = g_hash_table_new_full (g_str_hash, g_str_equal,
|
||||
(GDestroyNotify) g_free,
|
||||
(GDestroyNotify) g_free);
|
||||
|
||||
return provider;
|
||||
}
|
||||
|
||||
ShellMobileProvider *
|
||||
shell_mobile_provider_ref (ShellMobileProvider *provider)
|
||||
{
|
||||
provider->refs++;
|
||||
|
||||
return provider;
|
||||
}
|
||||
|
||||
void
|
||||
shell_mobile_provider_unref (ShellMobileProvider *provider)
|
||||
{
|
||||
if (--provider->refs == 0) {
|
||||
g_free (provider->name);
|
||||
g_hash_table_destroy (provider->lcl_names);
|
||||
|
||||
g_slist_foreach (provider->methods, (GFunc) shell_mobile_access_method_unref, NULL);
|
||||
g_slist_free (provider->methods);
|
||||
|
||||
g_slist_foreach (provider->gsm_mcc_mnc, (GFunc) mcc_mnc_free, NULL);
|
||||
g_slist_free (provider->gsm_mcc_mnc);
|
||||
|
||||
g_slist_free (provider->cdma_sid);
|
||||
|
||||
g_slice_free (ShellMobileProvider, provider);
|
||||
}
|
||||
}
|
||||
|
||||
GType
|
||||
shell_mobile_provider_get_type (void)
|
||||
{
|
||||
static GType type = 0;
|
||||
|
||||
if (G_UNLIKELY (type == 0)) {
|
||||
type = g_boxed_type_register_static ("ShellMobileProvider",
|
||||
(GBoxedCopyFunc) shell_mobile_provider_ref,
|
||||
(GBoxedFreeFunc) shell_mobile_provider_unref);
|
||||
}
|
||||
return type;
|
||||
}
|
||||
|
||||
static ShellCountryMobileProvider *
|
||||
country_mobile_provider_new (const char *country_code,
|
||||
const gchar *country_name)
|
||||
{
|
||||
ShellCountryMobileProvider *country_provider;
|
||||
|
||||
country_provider = g_slice_new0 (ShellCountryMobileProvider);
|
||||
country_provider->refs = 1;
|
||||
country_provider->country_code = g_strdup (country_code);
|
||||
country_provider->country_name = g_strdup (country_name);
|
||||
return country_provider;
|
||||
}
|
||||
|
||||
ShellCountryMobileProvider *
|
||||
shell_country_mobile_provider_ref (ShellCountryMobileProvider *country_provider)
|
||||
{
|
||||
country_provider->refs++;
|
||||
|
||||
return country_provider;
|
||||
}
|
||||
|
||||
void
|
||||
shell_country_mobile_provider_unref (ShellCountryMobileProvider *country_provider)
|
||||
{
|
||||
if (--country_provider->refs == 0) {
|
||||
g_free (country_provider->country_code);
|
||||
g_free (country_provider->country_name);
|
||||
g_slist_free_full (country_provider->providers,
|
||||
(GDestroyNotify) shell_mobile_provider_unref);
|
||||
g_slice_free (ShellCountryMobileProvider, country_provider);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* shell_country_mobile_provider_get_country_code:
|
||||
*
|
||||
* Returns: (transfer none): the code of the country.
|
||||
*/
|
||||
const gchar *
|
||||
shell_country_mobile_provider_get_country_code (ShellCountryMobileProvider *country_provider)
|
||||
{
|
||||
return country_provider->country_code;
|
||||
}
|
||||
|
||||
/**
|
||||
* shell_country_mobile_provider_get_country_name:
|
||||
*
|
||||
* Returns: (transfer none): the name of the country.
|
||||
*/
|
||||
const gchar *
|
||||
shell_country_mobile_provider_get_country_name (ShellCountryMobileProvider *country_provider)
|
||||
{
|
||||
return country_provider->country_name;
|
||||
}
|
||||
|
||||
/**
|
||||
* shell_country_mobile_provider_get_providers:
|
||||
*
|
||||
* Returns: (element-type Shell.MobileProvider) (transfer none): the
|
||||
* list of #ShellMobileProvider this country exposes.
|
||||
*/
|
||||
GSList *
|
||||
shell_country_mobile_provider_get_providers (ShellCountryMobileProvider *country_provider)
|
||||
{
|
||||
return country_provider->providers;
|
||||
}
|
||||
|
||||
GType
|
||||
shell_country_mobile_provider_get_type (void)
|
||||
{
|
||||
static GType type = 0;
|
||||
|
||||
if (G_UNLIKELY (type == 0)) {
|
||||
type = g_boxed_type_register_static ("ShellCountryMobileProvider",
|
||||
(GBoxedCopyFunc) shell_country_mobile_provider_ref,
|
||||
(GBoxedFreeFunc) shell_country_mobile_provider_unref);
|
||||
}
|
||||
return type;
|
||||
}
|
||||
|
||||
static void
|
||||
provider_list_free (gpointer data)
|
||||
{
|
||||
GSList *list = (GSList *) data;
|
||||
|
||||
while (list) {
|
||||
shell_mobile_provider_unref ((ShellMobileProvider *) list->data);
|
||||
list = g_slist_delete_link (list, list);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
parser_toplevel_start (MobileParser *parser,
|
||||
const char *name,
|
||||
const char **attribute_names,
|
||||
const char **attribute_values)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (!strcmp (name, "serviceproviders")) {
|
||||
for (i = 0; attribute_names && attribute_names[i]; i++) {
|
||||
if (!strcmp (attribute_names[i], "format")) {
|
||||
if (strcmp (attribute_values[i], "2.0")) {
|
||||
g_warning ("%s: mobile broadband provider database format '%s'"
|
||||
" not supported.", __func__, attribute_values[i]);
|
||||
parser->state = PARSER_ERROR;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (!strcmp (name, "country")) {
|
||||
for (i = 0; attribute_names && attribute_names[i]; i++) {
|
||||
if (!strcmp (attribute_names[i], "code")) {
|
||||
char *country_code;
|
||||
ShellCountryMobileProvider *country_provider;
|
||||
|
||||
country_code = g_ascii_strup (attribute_values[i], -1);
|
||||
country_provider = g_hash_table_lookup (parser->table, country_code);
|
||||
/* Ensure we have a country provider for this country code */
|
||||
if (!country_provider) {
|
||||
g_warning ("%s: adding providers for unknown country '%s'", __func__, country_code);
|
||||
country_provider = country_mobile_provider_new (country_code, NULL);
|
||||
g_hash_table_insert (parser->table, country_code, country_provider);
|
||||
}
|
||||
parser->current_country = country_code;
|
||||
|
||||
parser->state = PARSER_COUNTRY;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
parser_country_start (MobileParser *parser,
|
||||
const char *name,
|
||||
const char **attribute_names,
|
||||
const char **attribute_values)
|
||||
{
|
||||
if (!strcmp (name, "provider")) {
|
||||
parser->state = PARSER_PROVIDER;
|
||||
parser->current_provider = provider_new ();
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
parser_provider_start (MobileParser *parser,
|
||||
const char *name,
|
||||
const char **attribute_names,
|
||||
const char **attribute_values)
|
||||
{
|
||||
if (!strcmp (name, "gsm"))
|
||||
parser->state = PARSER_METHOD_GSM;
|
||||
else if (!strcmp (name, "cdma")) {
|
||||
parser->state = PARSER_METHOD_CDMA;
|
||||
parser->current_method = access_method_new ();
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
parser_gsm_start (MobileParser *parser,
|
||||
const char *name,
|
||||
const char **attribute_names,
|
||||
const char **attribute_values)
|
||||
{
|
||||
if (!strcmp (name, "network-id")) {
|
||||
const char *mcc = NULL, *mnc = NULL;
|
||||
int i;
|
||||
|
||||
for (i = 0; attribute_names && attribute_names[i]; i++) {
|
||||
if (!strcmp (attribute_names[i], "mcc"))
|
||||
mcc = attribute_values[i];
|
||||
else if (!strcmp (attribute_names[i], "mnc"))
|
||||
mnc = attribute_values[i];
|
||||
|
||||
if (mcc && strlen (mcc) && mnc && strlen (mnc)) {
|
||||
parser->current_provider->gsm_mcc_mnc = g_slist_prepend (parser->current_provider->gsm_mcc_mnc,
|
||||
mcc_mnc_new (mcc, mnc));
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else if (!strcmp (name, "apn")) {
|
||||
int i;
|
||||
|
||||
for (i = 0; attribute_names && attribute_names[i]; i++) {
|
||||
if (!strcmp (attribute_names[i], "value")) {
|
||||
|
||||
parser->state = PARSER_METHOD_GSM_APN;
|
||||
parser->current_method = access_method_new ();
|
||||
parser->current_method->gsm_apn = g_strstrip (g_strdup (attribute_values[i]));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
parser_cdma_start (MobileParser *parser,
|
||||
const char *name,
|
||||
const char **attribute_names,
|
||||
const char **attribute_values)
|
||||
{
|
||||
if (!strcmp (name, "sid")) {
|
||||
int i;
|
||||
|
||||
for (i = 0; attribute_names && attribute_names[i]; i++) {
|
||||
if (!strcmp (attribute_names[i], "value")) {
|
||||
unsigned long tmp;
|
||||
|
||||
errno = 0;
|
||||
tmp = strtoul (attribute_values[i], NULL, 10);
|
||||
if (errno == 0 && tmp > 0)
|
||||
parser->current_provider->cdma_sid = g_slist_prepend (parser->current_provider->cdma_sid,
|
||||
GUINT_TO_POINTER ((guint32) tmp));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
mobile_parser_start_element (GMarkupParseContext *context,
|
||||
const gchar *element_name,
|
||||
const gchar **attribute_names,
|
||||
const gchar **attribute_values,
|
||||
gpointer data,
|
||||
GError **error)
|
||||
{
|
||||
MobileParser *parser = (MobileParser *) data;
|
||||
|
||||
if (parser->text_buffer) {
|
||||
g_free (parser->text_buffer);
|
||||
parser->text_buffer = NULL;
|
||||
}
|
||||
|
||||
switch (parser->state) {
|
||||
case PARSER_TOPLEVEL:
|
||||
parser_toplevel_start (parser, element_name, attribute_names, attribute_values);
|
||||
break;
|
||||
case PARSER_COUNTRY:
|
||||
parser_country_start (parser, element_name, attribute_names, attribute_values);
|
||||
break;
|
||||
case PARSER_PROVIDER:
|
||||
parser_provider_start (parser, element_name, attribute_names, attribute_values);
|
||||
break;
|
||||
case PARSER_METHOD_GSM:
|
||||
parser_gsm_start (parser, element_name, attribute_names, attribute_values);
|
||||
break;
|
||||
case PARSER_METHOD_CDMA:
|
||||
parser_cdma_start (parser, element_name, attribute_names, attribute_values);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
parser_country_end (MobileParser *parser,
|
||||
const char *name)
|
||||
{
|
||||
if (!strcmp (name, "country")) {
|
||||
ShellCountryMobileProvider *country_provider;
|
||||
|
||||
country_provider = g_hash_table_lookup (parser->table, parser->current_country);
|
||||
if (country_provider)
|
||||
/* Store providers for this country */
|
||||
country_provider->providers = parser->current_providers;
|
||||
|
||||
parser->current_country = NULL;
|
||||
parser->current_providers = NULL;
|
||||
parser->text_buffer = NULL;
|
||||
parser->state = PARSER_TOPLEVEL;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
parser_provider_end (MobileParser *parser,
|
||||
const char *name)
|
||||
{
|
||||
if (!strcmp (name, "name")) {
|
||||
if (!parser->current_provider->name) {
|
||||
/* Use the first one. */
|
||||
parser->current_provider->name = parser->text_buffer;
|
||||
parser->text_buffer = NULL;
|
||||
}
|
||||
} else if (!strcmp (name, "provider")) {
|
||||
parser->current_provider->methods = g_slist_reverse (parser->current_provider->methods);
|
||||
|
||||
parser->current_provider->gsm_mcc_mnc = g_slist_reverse (parser->current_provider->gsm_mcc_mnc);
|
||||
parser->current_provider->cdma_sid = g_slist_reverse (parser->current_provider->cdma_sid);
|
||||
|
||||
parser->current_providers = g_slist_prepend (parser->current_providers, parser->current_provider);
|
||||
parser->current_provider = NULL;
|
||||
parser->text_buffer = NULL;
|
||||
parser->state = PARSER_COUNTRY;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
parser_gsm_end (MobileParser *parser,
|
||||
const char *name)
|
||||
{
|
||||
if (!strcmp (name, "gsm")) {
|
||||
parser->text_buffer = NULL;
|
||||
parser->state = PARSER_PROVIDER;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
parser_gsm_apn_end (MobileParser *parser,
|
||||
const char *name)
|
||||
{
|
||||
if (!strcmp (name, "name")) {
|
||||
if (!parser->current_method->name) {
|
||||
/* Use the first one. */
|
||||
parser->current_method->name = parser->text_buffer;
|
||||
parser->text_buffer = NULL;
|
||||
}
|
||||
} else if (!strcmp (name, "username")) {
|
||||
parser->current_method->username = parser->text_buffer;
|
||||
parser->text_buffer = NULL;
|
||||
} else if (!strcmp (name, "password")) {
|
||||
parser->current_method->password = parser->text_buffer;
|
||||
parser->text_buffer = NULL;
|
||||
} else if (!strcmp (name, "dns")) {
|
||||
parser->current_method->dns = g_slist_prepend (parser->current_method->dns, parser->text_buffer);
|
||||
parser->text_buffer = NULL;
|
||||
} else if (!strcmp (name, "gateway")) {
|
||||
parser->current_method->gateway = parser->text_buffer;
|
||||
parser->text_buffer = NULL;
|
||||
} else if (!strcmp (name, "apn")) {
|
||||
parser->current_method->type = SHELL_MOBILE_ACCESS_METHOD_TYPE_GSM;
|
||||
parser->current_method->dns = g_slist_reverse (parser->current_method->dns);
|
||||
|
||||
if (!parser->current_method->name)
|
||||
parser->current_method->name = g_strdup (_("Default"));
|
||||
|
||||
parser->current_provider->methods = g_slist_prepend (parser->current_provider->methods,
|
||||
parser->current_method);
|
||||
parser->current_method = NULL;
|
||||
parser->text_buffer = NULL;
|
||||
parser->state = PARSER_METHOD_GSM;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
parser_cdma_end (MobileParser *parser,
|
||||
const char *name)
|
||||
{
|
||||
if (!strcmp (name, "username")) {
|
||||
parser->current_method->username = parser->text_buffer;
|
||||
parser->text_buffer = NULL;
|
||||
} else if (!strcmp (name, "password")) {
|
||||
parser->current_method->password = parser->text_buffer;
|
||||
parser->text_buffer = NULL;
|
||||
} else if (!strcmp (name, "dns")) {
|
||||
parser->current_method->dns = g_slist_prepend (parser->current_method->dns, parser->text_buffer);
|
||||
parser->text_buffer = NULL;
|
||||
} else if (!strcmp (name, "gateway")) {
|
||||
parser->current_method->gateway = parser->text_buffer;
|
||||
parser->text_buffer = NULL;
|
||||
} else if (!strcmp (name, "cdma")) {
|
||||
parser->current_method->type = SHELL_MOBILE_ACCESS_METHOD_TYPE_CDMA;
|
||||
parser->current_method->dns = g_slist_reverse (parser->current_method->dns);
|
||||
|
||||
if (!parser->current_method->name)
|
||||
parser->current_method->name = g_strdup (parser->current_provider->name);
|
||||
|
||||
parser->current_provider->methods = g_slist_prepend (parser->current_provider->methods,
|
||||
parser->current_method);
|
||||
parser->current_method = NULL;
|
||||
parser->text_buffer = NULL;
|
||||
parser->state = PARSER_PROVIDER;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
mobile_parser_end_element (GMarkupParseContext *context,
|
||||
const gchar *element_name,
|
||||
gpointer data,
|
||||
GError **error)
|
||||
{
|
||||
MobileParser *parser = (MobileParser *) data;
|
||||
|
||||
switch (parser->state) {
|
||||
case PARSER_COUNTRY:
|
||||
parser_country_end (parser, element_name);
|
||||
break;
|
||||
case PARSER_PROVIDER:
|
||||
parser_provider_end (parser, element_name);
|
||||
break;
|
||||
case PARSER_METHOD_GSM:
|
||||
parser_gsm_end (parser, element_name);
|
||||
break;
|
||||
case PARSER_METHOD_GSM_APN:
|
||||
parser_gsm_apn_end (parser, element_name);
|
||||
break;
|
||||
case PARSER_METHOD_CDMA:
|
||||
parser_cdma_end (parser, element_name);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
mobile_parser_characters (GMarkupParseContext *context,
|
||||
const gchar *text,
|
||||
gsize text_len,
|
||||
gpointer data,
|
||||
GError **error)
|
||||
{
|
||||
MobileParser *parser = (MobileParser *) data;
|
||||
|
||||
g_free (parser->text_buffer);
|
||||
parser->text_buffer = g_strdup (text);
|
||||
}
|
||||
|
||||
static const GMarkupParser mobile_parser = {
|
||||
mobile_parser_start_element,
|
||||
mobile_parser_end_element,
|
||||
mobile_parser_characters,
|
||||
NULL, /* passthrough */
|
||||
NULL /* error */
|
||||
};
|
||||
|
||||
/**
|
||||
* shell_mobile_providers_parse:
|
||||
* @country_codes: (allow-none) File with the list of country codes.
|
||||
* @service_providers: (allow-none) File with the list of service providers.
|
||||
*
|
||||
* Returns: (element-type utf8 Shell.CountryMobileProvider) (transfer full): a
|
||||
* hash table where keys are country names #gchar and values are #ShellCountryMobileProvider.
|
||||
* Everything is destroyed with g_hash_table_destroy().
|
||||
*/
|
||||
GHashTable *
|
||||
shell_mobile_providers_parse (const gchar *country_codes,
|
||||
const gchar *service_providers)
|
||||
{
|
||||
GMarkupParseContext *ctx;
|
||||
GIOChannel *channel;
|
||||
MobileParser parser;
|
||||
GError *error = NULL;
|
||||
char buffer[4096];
|
||||
GIOStatus status;
|
||||
gsize len = 0;
|
||||
|
||||
/* Use default paths if none given */
|
||||
if (!country_codes)
|
||||
country_codes = ISO_3166_COUNTRY_CODES;
|
||||
if (!service_providers)
|
||||
service_providers = MOBILE_BROADBAND_PROVIDER_INFO;
|
||||
|
||||
memset (&parser, 0, sizeof (MobileParser));
|
||||
|
||||
parser.table = read_country_codes (country_codes);
|
||||
if (!parser.table)
|
||||
goto out;
|
||||
|
||||
channel = g_io_channel_new_file (service_providers, "r", &error);
|
||||
if (!channel) {
|
||||
if (error) {
|
||||
g_warning ("Could not read %s: %s", service_providers, error->message);
|
||||
g_error_free (error);
|
||||
} else
|
||||
g_warning ("Could not read %s: Unknown error", service_providers);
|
||||
|
||||
goto out;
|
||||
}
|
||||
|
||||
parser.state = PARSER_TOPLEVEL;
|
||||
|
||||
ctx = g_markup_parse_context_new (&mobile_parser, 0, &parser, NULL);
|
||||
|
||||
status = G_IO_STATUS_NORMAL;
|
||||
while (status == G_IO_STATUS_NORMAL) {
|
||||
status = g_io_channel_read_chars (channel, buffer, sizeof (buffer), &len, &error);
|
||||
|
||||
switch (status) {
|
||||
case G_IO_STATUS_NORMAL:
|
||||
if (!g_markup_parse_context_parse (ctx, buffer, len, &error)) {
|
||||
status = G_IO_STATUS_ERROR;
|
||||
g_warning ("Error while parsing XML: %s", error->message);
|
||||
g_error_free (error);;
|
||||
}
|
||||
break;
|
||||
case G_IO_STATUS_EOF:
|
||||
break;
|
||||
case G_IO_STATUS_ERROR:
|
||||
g_warning ("Error while reading: %s", error->message);
|
||||
g_error_free (error);
|
||||
break;
|
||||
case G_IO_STATUS_AGAIN:
|
||||
/* FIXME: Try again a few times, but really, it never happes, right? */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
g_io_channel_unref (channel);
|
||||
g_markup_parse_context_free (ctx);
|
||||
|
||||
if (parser.current_provider) {
|
||||
g_warning ("pending current provider");
|
||||
shell_mobile_provider_unref (parser.current_provider);
|
||||
}
|
||||
|
||||
if (parser.current_providers) {
|
||||
g_warning ("pending current providers");
|
||||
provider_list_free (parser.current_providers);
|
||||
}
|
||||
|
||||
g_free (parser.current_country);
|
||||
g_free (parser.text_buffer);
|
||||
|
||||
out:
|
||||
|
||||
return parser.table;
|
||||
}
|
||||
|
||||
static void
|
||||
dump_generic (ShellMobileAccessMethod *method)
|
||||
{
|
||||
GSList *iter;
|
||||
GString *dns;
|
||||
|
||||
g_print (" username: %s\n", method->username ? method->username : "");
|
||||
g_print (" password: %s\n", method->password ? method->password : "");
|
||||
|
||||
dns = g_string_new (NULL);
|
||||
for (iter = method->dns; iter; iter = g_slist_next (iter))
|
||||
g_string_append_printf (dns, "%s%s", dns->len ? ", " : "", (char *) iter->data);
|
||||
g_print (" dns : %s\n", dns->str);
|
||||
g_string_free (dns, TRUE);
|
||||
|
||||
g_print (" gateway : %s\n", method->gateway ? method->gateway : "");
|
||||
}
|
||||
|
||||
static void
|
||||
dump_cdma (ShellMobileAccessMethod *method)
|
||||
{
|
||||
g_print (" CDMA: %s\n", method->name);
|
||||
|
||||
dump_generic (method);
|
||||
}
|
||||
|
||||
static void
|
||||
dump_gsm (ShellMobileAccessMethod *method)
|
||||
{
|
||||
g_print (" APN: %s (%s)\n", method->name, method->gsm_apn);
|
||||
|
||||
dump_generic (method);
|
||||
}
|
||||
|
||||
static void
|
||||
dump_country (gpointer key, gpointer value, gpointer user_data)
|
||||
{
|
||||
GSList *miter, *citer;
|
||||
ShellCountryMobileProvider *country_provider = value;
|
||||
|
||||
g_print ("Country: %s (%s)\n",
|
||||
country_provider->country_code,
|
||||
country_provider->country_name);
|
||||
|
||||
for (citer = country_provider->providers; citer; citer = g_slist_next (citer)) {
|
||||
ShellMobileProvider *provider = citer->data;
|
||||
|
||||
g_print (" Provider: %s (%s)\n", provider->name, (const char *) key);
|
||||
for (miter = provider->methods; miter; miter = g_slist_next (miter)) {
|
||||
ShellMobileAccessMethod *method = miter->data;
|
||||
GSList *liter;
|
||||
|
||||
|
||||
for (liter = provider->gsm_mcc_mnc; liter; liter = g_slist_next (liter)) {
|
||||
ShellGsmMccMnc *m = liter->data;
|
||||
g_print (" MCC/MNC: %s-%s\n", m->mcc, m->mnc);
|
||||
}
|
||||
|
||||
for (liter = provider->cdma_sid; liter; liter = g_slist_next (liter))
|
||||
g_print (" SID: %d\n", GPOINTER_TO_UINT (liter->data));
|
||||
|
||||
switch (method->type) {
|
||||
case SHELL_MOBILE_ACCESS_METHOD_TYPE_CDMA:
|
||||
dump_cdma (method);
|
||||
break;
|
||||
case SHELL_MOBILE_ACCESS_METHOD_TYPE_GSM:
|
||||
dump_gsm (method);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
g_print ("\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
shell_mobile_providers_dump (GHashTable *country_providers)
|
||||
{
|
||||
g_return_if_fail (country_providers != NULL);
|
||||
g_hash_table_foreach (country_providers, dump_country, NULL);
|
||||
}
|
||||
|
||||
/* All the following don't exist in nm-applet, because C doesn't need
|
||||
those. They're only needed for the introspection annotations
|
||||
*/
|
||||
|
||||
/**
|
||||
* shell_mobile_provider_get_gsm_mcc_mnc:
|
||||
* @provider: a #ShellMobileProvider
|
||||
*
|
||||
* Returns: (element-type Shell.GsmMccMnc) (transfer none): the
|
||||
* list of #ShellGsmMccMnc this provider exposes
|
||||
*/
|
||||
GSList *
|
||||
shell_mobile_provider_get_gsm_mcc_mnc (ShellMobileProvider *provider)
|
||||
{
|
||||
return provider->gsm_mcc_mnc;
|
||||
}
|
||||
|
||||
/**
|
||||
* shell_mobile_provider_get_cdma_sid:
|
||||
* @provider: a #ShellMobileProvider
|
||||
*
|
||||
* Returns: (element-type guint32) (transfer none): the
|
||||
* list of CDMA sids this provider exposes
|
||||
*/
|
||||
GSList *
|
||||
shell_mobile_provider_get_cdma_sid (ShellMobileProvider *provider)
|
||||
{
|
||||
return provider->cdma_sid;
|
||||
}
|
@@ -1,111 +0,0 @@
|
||||
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
* Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Copyright (C) 2009 Novell, Inc.
|
||||
* Author: Tambet Ingo (tambet@gmail.com).
|
||||
*
|
||||
* Copyright (C) 2009 - 2010 Red Hat, Inc.
|
||||
*
|
||||
* Ported to GNOME Shell by Giovanni Campagna <scampa.giovanni@gmail.com>
|
||||
* Porting consisted only in replacing nmn with shell, to be compatible with
|
||||
* GObject Introspection namespacing
|
||||
*/
|
||||
|
||||
#ifndef SHELL_MOBILE_PROVIDERS_H
|
||||
#define SHELL_MOBILE_PROVIDERS_H
|
||||
|
||||
#include <glib.h>
|
||||
#include <glib-object.h>
|
||||
|
||||
#define SHELL_TYPE_MOBILE_PROVIDER (shell_mobile_provider_get_type ())
|
||||
#define SHELL_TYPE_MOBILE_ACCESS_METHOD (shell_mobile_access_method_get_type ())
|
||||
|
||||
typedef enum {
|
||||
SHELL_MOBILE_ACCESS_METHOD_TYPE_UNKNOWN = 0,
|
||||
SHELL_MOBILE_ACCESS_METHOD_TYPE_GSM,
|
||||
SHELL_MOBILE_ACCESS_METHOD_TYPE_CDMA
|
||||
} ShellMobileAccessMethodType;
|
||||
|
||||
typedef struct {
|
||||
char *mcc;
|
||||
char *mnc;
|
||||
} ShellGsmMccMnc;
|
||||
|
||||
typedef struct {
|
||||
char *name;
|
||||
/* maps lang (char *) -> name (char *) */
|
||||
GHashTable *lcl_names;
|
||||
|
||||
char *username;
|
||||
char *password;
|
||||
char *gateway;
|
||||
GSList *dns; /* GSList of 'char *' */
|
||||
|
||||
/* Only used with SHELL_PROVIDER_TYPE_GSM */
|
||||
char *gsm_apn;
|
||||
|
||||
ShellMobileAccessMethodType type;
|
||||
|
||||
gint refs;
|
||||
} ShellMobileAccessMethod;
|
||||
|
||||
typedef struct {
|
||||
char *name;
|
||||
/* maps lang (char *) -> name (char *) */
|
||||
GHashTable *lcl_names;
|
||||
|
||||
GSList *methods; /* GSList of ShellMobileAccessMethod */
|
||||
|
||||
GSList *gsm_mcc_mnc; /* GSList of ShellGsmMccMnc */
|
||||
GSList *cdma_sid; /* GSList of guint32 */
|
||||
|
||||
gint refs;
|
||||
} ShellMobileProvider;
|
||||
|
||||
typedef struct {
|
||||
char *country_code;
|
||||
char *country_name;
|
||||
GSList *providers;
|
||||
|
||||
gint refs;
|
||||
} ShellCountryMobileProvider;
|
||||
|
||||
|
||||
GType shell_gsm_mcc_mnc_get_type (void); /* added in porting */
|
||||
GType shell_mobile_access_method_get_type (void);
|
||||
GType shell_mobile_provider_get_type (void);
|
||||
GType shell_country_mobile_provider_get_type (void);
|
||||
|
||||
ShellMobileProvider *shell_mobile_provider_ref (ShellMobileProvider *provider);
|
||||
void shell_mobile_provider_unref (ShellMobileProvider *provider);
|
||||
GSList * shell_mobile_provider_get_gsm_mcc_mnc (ShellMobileProvider *provider);
|
||||
GSList * shell_mobile_provider_get_cdma_sid (ShellMobileProvider *provider);
|
||||
|
||||
ShellMobileAccessMethod *shell_mobile_access_method_ref (ShellMobileAccessMethod *method);
|
||||
void shell_mobile_access_method_unref (ShellMobileAccessMethod *method);
|
||||
|
||||
ShellCountryMobileProvider *shell_country_mobile_provider_ref (ShellCountryMobileProvider *country_provider);
|
||||
void shell_country_mobile_provider_unref (ShellCountryMobileProvider *country_provider);
|
||||
const gchar *shell_country_mobile_provider_get_country_code (ShellCountryMobileProvider *country_provider);
|
||||
const gchar *shell_country_mobile_provider_get_country_name (ShellCountryMobileProvider *country_provider);
|
||||
GSList *shell_country_mobile_provider_get_providers (ShellCountryMobileProvider *country_provider);
|
||||
|
||||
GHashTable *shell_mobile_providers_parse (const gchar *country_codes,
|
||||
const gchar *service_providers);
|
||||
void shell_mobile_providers_dump (GHashTable *country_providers);
|
||||
|
||||
#endif /* SHELL_MOBILE_PROVIDERS_H */
|
Reference in New Issue
Block a user