[network-manager-netbook] Update the mobile providers parser to parse the format "2.0".
- From: Tambet Ingo <tambeti src gnome org>
- To: svn-commits-list gnome org
- Subject: [network-manager-netbook] Update the mobile providers parser to parse the format "2.0".
- Date: Thu, 4 Jun 2009 06:33:55 -0400 (EDT)
commit 15e821630a7cd6f7a2d3ee5f8daffb72b6a06a9c
Author: Tambet Ingo <tambet gmail com>
Date: Thu Jun 4 13:32:39 2009 +0300
Update the mobile providers parser to parse the format "2.0".
Use the new MCC and MNC in created mobile connections.
---
src/nmn-mobile-providers.c | 409 +++++++++++++++++++++++++++++++++++++++++---
src/nmn-mobile-providers.h | 45 +++++-
src/nmn-new-connection.c | 168 +++++++++++++-----
3 files changed, 548 insertions(+), 74 deletions(-)
diff --git a/src/nmn-mobile-providers.c b/src/nmn-mobile-providers.c
index bd582a0..d8d4ecf 100644
--- a/src/nmn-mobile-providers.c
+++ b/src/nmn-mobile-providers.c
@@ -20,6 +20,11 @@
*/
#include <string.h>
+#include <errno.h>
+#include <stdlib.h>
+
+#include <glib/gi18n.h>
+
#include "nmn-mobile-providers.h"
#define ISO_3166_COUNTRY_CODES "/usr/share/zoneinfo/iso3166.tab"
@@ -86,7 +91,11 @@ read_country_codes (void)
typedef enum {
PARSER_TOPLEVEL = 0,
PARSER_COUNTRY,
- PARSER_PROVIDER
+ PARSER_PROVIDER,
+ PARSER_METHOD_GSM,
+ PARSER_METHOD_GSM_APN,
+ PARSER_METHOD_CDMA,
+ PARSER_ERROR
} MobileContextState;
typedef struct {
@@ -96,11 +105,111 @@ typedef struct {
char *current_country;
GSList *current_providers;
NmnMobileProvider *current_provider;
+ NmnMobileAccessMethod *current_method;
+ GSList *mcc_mncs;
char *text_buffer;
MobileContextState state;
} MobileParser;
+static NmnGsmMccMnc *
+mcc_mnc_new (const char *mcc, const char *mnc)
+{
+ NmnGsmMccMnc *m;
+
+ m = g_slice_new0 (NmnGsmMccMnc);
+ m->mcc = g_strdup (mcc);
+ m->mnc = g_strdup (mnc);
+ return m;
+}
+
+static void
+mcc_mnc_free (NmnGsmMccMnc *m)
+{
+ g_return_if_fail (m != NULL);
+ g_free (m->mcc);
+ g_free (m->mnc);
+ g_slice_free (NmnGsmMccMnc, m);
+}
+
+static GSList *
+mcc_mnc_list_copy (GSList *list)
+{
+ GSList *iter, *ret = NULL;
+
+ for (iter = list; iter; iter = g_slist_next (iter)) {
+ NmnGsmMccMnc *m = iter->data;
+
+ ret = g_slist_prepend (ret, mcc_mnc_new (m->mcc, m->mnc));
+ }
+
+ return g_slist_reverse (ret);
+}
+
+static NmnMobileAccessMethod *
+access_method_new (void)
+{
+ NmnMobileAccessMethod *method;
+
+ method = g_slice_new0 (NmnMobileAccessMethod);
+ 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;
+}
+
+NmnMobileAccessMethod *
+nmn_mobile_access_method_ref (NmnMobileAccessMethod *method)
+{
+ g_return_val_if_fail (method != NULL, NULL);
+ g_return_val_if_fail (method->refs > 0, NULL);
+
+ method->refs++;
+
+ return method;
+}
+
+void
+nmn_mobile_access_method_unref (NmnMobileAccessMethod *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_slist_foreach (method->gsm_mcc_mnc, (GFunc) mcc_mnc_free, NULL);
+ g_slist_free (method->gsm_mcc_mnc);
+
+ g_slist_free (method->cdma_sid);
+
+ g_slice_free (NmnMobileAccessMethod, method);
+ }
+}
+
+GType
+nmn_mobile_access_method_get_type (void)
+{
+ static GType type = 0;
+
+ if (G_UNLIKELY (type == 0)) {
+ type = g_boxed_type_register_static ("NmnMobileAccessMethod",
+ (GBoxedCopyFunc) nmn_mobile_access_method_ref,
+ (GBoxedFreeFunc) nmn_mobile_access_method_unref);
+ }
+ return type;
+}
+
+
static NmnMobileProvider *
provider_new (void)
{
@@ -108,6 +217,9 @@ provider_new (void)
provider = g_slice_new0 (NmnMobileProvider);
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;
}
@@ -125,12 +237,10 @@ nmn_mobile_provider_unref (NmnMobileProvider *provider)
{
if (--provider->refs == 0) {
g_free (provider->name);
- g_free (provider->username);
- g_free (provider->password);
- g_free (provider->gateway);
- g_free (provider->apn);
- g_slist_foreach (provider->dns, (GFunc) g_free, NULL);
- g_slist_free (provider->dns);
+ g_hash_table_destroy (provider->lcl_names);
+
+ g_slist_foreach (provider->methods, (GFunc) nmn_mobile_access_method_unref, NULL);
+ g_slist_free (provider->methods);
g_slice_free (NmnMobileProvider, provider);
}
@@ -141,11 +251,11 @@ nmn_mobile_provider_get_type (void)
{
static GType type = 0;
- if (G_UNLIKELY (type == 0))
+ if (G_UNLIKELY (type == 0)) {
type = g_boxed_type_register_static ("NmnMobileProvider",
(GBoxedCopyFunc) nmn_mobile_provider_ref,
(GBoxedFreeFunc) nmn_mobile_provider_unref);
-
+ }
return type;
}
@@ -168,7 +278,18 @@ parser_toplevel_start (MobileParser *parser,
{
int i;
- if (!strcmp (name, "country")) {
+ 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;
@@ -202,6 +323,80 @@ parser_country_start (MobileParser *parser,
}
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->mcc_mncs = g_slist_append (parser->mcc_mncs, 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_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_method->cdma_sid = g_slist_prepend (parser->current_method->cdma_sid,
+ GUINT_TO_POINTER ((guint32) tmp));
+ break;
+ }
+ }
+ }
+}
+
+static void
mobile_parser_start_element (GMarkupParseContext *context,
const gchar *element_name,
const gchar **attribute_names,
@@ -223,6 +418,15 @@ mobile_parser_start_element (GMarkupParseContext *context,
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;
}
@@ -250,28 +454,92 @@ parser_provider_end (MobileParser *parser,
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_providers = g_slist_prepend (parser->current_providers, parser->current_provider);
+ parser->current_provider = NULL;
+ parser->state = PARSER_COUNTRY;
+ }
+}
+
+static void
+parser_gsm_end (MobileParser *parser,
+ const char *name)
+{
+ if (!strcmp (name, "gsm")) {
+ g_slist_foreach (parser->mcc_mncs, (GFunc) mcc_mnc_free, NULL);
+ g_slist_free (parser->mcc_mncs);
+ parser->mcc_mncs = 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_provider->username = parser->text_buffer;
+ parser->current_method->username = parser->text_buffer;
parser->text_buffer = NULL;
} else if (!strcmp (name, "password")) {
- parser->current_provider->password = parser->text_buffer;
+ parser->current_method->password = parser->text_buffer;
parser->text_buffer = NULL;
} else if (!strcmp (name, "dns")) {
- parser->current_provider->dns = g_slist_prepend (parser->current_provider->dns, parser->text_buffer);
+ 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_provider->gateway = parser->text_buffer;
+ parser->current_method->gateway = parser->text_buffer;
parser->text_buffer = NULL;
} else if (!strcmp (name, "apn")) {
- parser->current_provider->apn = parser->text_buffer;
+ parser->current_method->type = NMN_MOBILE_ACCESS_METHOD_TYPE_GSM;
+ parser->current_method->dns = g_slist_reverse (parser->current_method->dns);
+ parser->current_method->gsm_mcc_mnc = mcc_mnc_list_copy (parser->mcc_mncs);
+
+ 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->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_provider->type = NMN_PROVIDER_TYPE_CDMA;
- } else if (!strcmp (name, "provider")) {
- parser->current_provider->dns = g_slist_reverse (parser->current_provider->dns);
- parser->current_providers = g_slist_prepend (parser->current_providers, parser->current_provider);
- parser->current_provider = NULL;
- parser->state = PARSER_COUNTRY;
+ parser->current_method->type = NMN_MOBILE_ACCESS_METHOD_TYPE_CDMA;
+ parser->current_method->dns = g_slist_reverse (parser->current_method->dns);
+ parser->current_method->cdma_sid = g_slist_reverse (parser->current_method->cdma_sid);
+
+ 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->state = PARSER_PROVIDER;
}
}
@@ -290,6 +558,15 @@ mobile_parser_end_element (GMarkupParseContext *context,
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;
}
@@ -317,7 +594,7 @@ static const GMarkupParser mobile_parser = {
};
GHashTable *
-nmn_mobile_providers_parse (void)
+nmn_mobile_providers_parse (GHashTable **out_ccs)
{
GMarkupParseContext *ctx;
GIOChannel *channel;
@@ -390,8 +667,92 @@ nmn_mobile_providers_parse (void)
g_free (parser.text_buffer);
out:
- if (parser.country_codes)
- g_hash_table_destroy (parser.country_codes);
+ if (parser.country_codes) {
+ if (out_ccs)
+ *out_ccs = parser.country_codes;
+ else
+ g_hash_table_destroy (parser.country_codes);
+ }
return parser.table;
}
+
+static void
+dump_generic (NmnMobileAccessMethod *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 (NmnMobileAccessMethod *method)
+{
+ GSList *iter;
+
+ g_print (" CDMA: %s\n", method->name);
+
+ dump_generic (method);
+
+ for (iter = method->cdma_sid; iter; iter = g_slist_next (iter))
+ g_print (" SID: %d\n", GPOINTER_TO_UINT (iter->data));
+}
+
+static void
+dump_gsm (NmnMobileAccessMethod *method)
+{
+ GSList *iter;
+
+ g_print (" APN: %s (%s)\n", method->name, method->gsm_apn);
+
+ dump_generic (method);
+
+ for (iter = method->gsm_mcc_mnc; iter; iter = g_slist_next (iter)) {
+ NmnGsmMccMnc *m = iter->data;
+ g_print (" MCC/MNC: %s-%s\n", m->mcc, m->mnc);
+ }
+}
+
+static void
+dump_country (gpointer key, gpointer value, gpointer user_data)
+{
+ GSList *citer, *miter;
+
+ for (citer = value; citer; citer = g_slist_next (citer)) {
+ NmnMobileProvider *provider = citer->data;
+
+ g_print ("Provider: %s (%s)\n", provider->name, (const char *) key);
+ for (miter = provider->methods; miter; miter = g_slist_next (miter)) {
+ NmnMobileAccessMethod *method = miter->data;
+
+ switch (method->type) {
+ case NMN_MOBILE_ACCESS_METHOD_TYPE_CDMA:
+ dump_cdma (method);
+ break;
+ case NMN_MOBILE_ACCESS_METHOD_TYPE_GSM:
+ dump_gsm (method);
+ break;
+ default:
+ break;
+ }
+ g_print ("\n");
+ }
+ }
+}
+
+void
+nmn_mobile_providers_dump (GHashTable *providers)
+{
+ g_return_if_fail (providers != NULL);
+ g_hash_table_foreach (providers, dump_country, NULL);
+}
diff --git a/src/nmn-mobile-providers.h b/src/nmn-mobile-providers.h
index 5c0c158..371fdef 100644
--- a/src/nmn-mobile-providers.h
+++ b/src/nmn-mobile-providers.h
@@ -26,34 +26,67 @@
#include <glib-object.h>
#define NMN_TYPE_MOBILE_PROVIDER (nmn_mobile_provider_get_type ())
+#define NMN_TYPE_MOBILE_ACCESS_METHOD (nmn_mobile_access_method_get_type ())
typedef enum {
- NMN_PROVIDER_TYPE_GSM = 0,
- NMN_PROVIDER_TYPE_CDMA
+ NMN_MOBILE_ACCESS_METHOD_TYPE_UNKNOWN = 0,
+ NMN_MOBILE_ACCESS_METHOD_TYPE_GSM,
+ NMN_MOBILE_ACCESS_METHOD_TYPE_CDMA
} NmnMobileProviderType;
typedef struct {
+ char *mcc;
+ char *mnc;
+} NmnGsmMccMnc;
+
+typedef struct {
char *name;
+ /* maps lang (char *) -> name (char *) */
+ GHashTable *lcl_names;
+
char *username;
char *password;
char *gateway;
- char *apn;
GSList *dns; /* GSList of 'char *' */
+
+ /* Only used with NMN_PROVIDER_TYPE_GSM */
+ char *gsm_apn;
+ GSList *gsm_mcc_mnc; /* GSList of NmnGsmMccMnc */
+
+ /* Only used with NMN_PROVIDER_TYPE_CDMA */
+ GSList *cdma_sid; /* GSList of guint32 */
+
NmnMobileProviderType type;
gint refs;
+} NmnMobileAccessMethod;
+
+typedef struct {
+ char *name;
+ /* maps lang (char *) -> name (char *) */
+ GHashTable *lcl_names;
+
+ GSList *methods; /* GSList of NmnMobileAccessMethod */
+
+ gint refs;
} NmnMobileProvider;
+
GType nmn_mobile_provider_get_type (void);
+GType nmn_mobile_access_method_get_type (void);
NmnMobileProvider *nmn_mobile_provider_ref (NmnMobileProvider *provider);
-void nmn_mobile_provider_unref (NmnMobileProvider *provider);
+void nmn_mobile_provider_unref (NmnMobileProvider *provider);
+
+NmnMobileAccessMethod *nmn_mobile_access_method_ref (NmnMobileAccessMethod *method);
+void nmn_mobile_access_method_unref (NmnMobileAccessMethod *method);
/* Returns a hash table where keys are country names 'char *',
- values are NmnMobileProvider structures.
+ values are a 'GSList *' of 'NmnMobileProvider *'.
Everything is destroyed with g_hash_table_destroy (). */
-GHashTable *nmn_mobile_providers_parse (void);
+GHashTable *nmn_mobile_providers_parse (GHashTable **out_ccs);
+void nmn_mobile_providers_dump (GHashTable *providers);
#endif /* NMN_MOBILE_PROVIDERS_H */
diff --git a/src/nmn-new-connection.c b/src/nmn-new-connection.c
index 907392e..2b9d03f 100644
--- a/src/nmn-new-connection.c
+++ b/src/nmn-new-connection.c
@@ -94,8 +94,9 @@ wifi_page_init (NmnNewConnection *connection)
/* Mobile */
-#define MOBILE_COL_NAME 0
-#define MOBILE_COL_DATA 1
+#define MOBILE_COL_NAME 0
+#define MOBILE_COL_PROVIDER 1
+#define MOBILE_COL_METHOD 2
static gboolean
mobile_have_device (NmnNewConnection *connection, NmnMobileProviderType *type)
@@ -111,12 +112,12 @@ mobile_have_device (NmnNewConnection *connection, NmnMobileProviderType *type)
if (NM_IS_GSM_DEVICE (device)) {
found = TRUE;
- *type = NMN_PROVIDER_TYPE_GSM;
+ *type = NMN_MOBILE_ACCESS_METHOD_TYPE_GSM;
}
if (NM_IS_CDMA_DEVICE (device)) {
found = TRUE;
- *type = NMN_PROVIDER_TYPE_CDMA;
+ *type = NMN_MOBILE_ACCESS_METHOD_TYPE_CDMA;
}
}
@@ -147,6 +148,21 @@ mobile_status_update (NmnNewConnection *connection)
}
static gboolean
+method_list_has_type (GSList *list, NmnMobileProviderType type)
+{
+ GSList *iter;
+
+ for (iter = list; iter; iter = iter->next) {
+ NmnMobileAccessMethod *method = iter->data;
+
+ if (method->type == type)
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+static gboolean
provider_list_has_type (GSList *list, NmnMobileProviderType type)
{
GSList *iter;
@@ -154,7 +170,7 @@ provider_list_has_type (GSList *list, NmnMobileProviderType type)
for (iter = list; iter; iter = iter->next) {
NmnMobileProvider *provider = (NmnMobileProvider *) iter->data;
- if (provider->type == type)
+ if (method_list_has_type (provider->methods, type))
return TRUE;
}
@@ -164,37 +180,80 @@ provider_list_has_type (GSList *list, NmnMobileProviderType type)
typedef struct {
GtkTreeStore *store;
NmnMobileProviderType provider_type;
+
+ GtkTreeIter *parent_iter;
} MobilePopulateInfo;
static void
+add_one_method (gpointer data, gpointer user_data)
+{
+ NmnMobileAccessMethod *method = (NmnMobileAccessMethod *) data;
+ MobilePopulateInfo *info = (MobilePopulateInfo *) user_data;
+ GtkTreeIter iter;
+
+ if (method->type != info->provider_type)
+ return;
+
+ gtk_tree_store_append (info->store, &iter, info->parent_iter);
+
+ if (method->type == NMN_MOBILE_ACCESS_METHOD_TYPE_GSM) {
+ char *txt;
+
+ txt = g_strdup_printf ("%s (APN %s)", method->name, method->gsm_apn);
+ gtk_tree_store_set (info->store, &iter,
+ MOBILE_COL_NAME, txt,
+ MOBILE_COL_METHOD, method,
+ -1);
+
+ g_free (txt);
+ } else {
+ gtk_tree_store_set (info->store, &iter,
+ MOBILE_COL_NAME, method->name,
+ MOBILE_COL_METHOD, method,
+ -1);
+ }
+}
+
+static void
+add_one_provider (gpointer data, gpointer user_data)
+{
+ NmnMobileProvider *provider = (NmnMobileProvider *) data;
+ MobilePopulateInfo *info = (MobilePopulateInfo *) user_data;
+ GtkTreeIter *country_iter;
+ GtkTreeIter iter;
+
+ if (!method_list_has_type (provider->methods, info->provider_type))
+ return;
+
+ gtk_tree_store_append (info->store, &iter, info->parent_iter);
+ gtk_tree_store_set (info->store, &iter,
+ MOBILE_COL_NAME, provider->name,
+ MOBILE_COL_PROVIDER, provider,
+ -1);
+
+ country_iter = info->parent_iter;
+ info->parent_iter = &iter;
+ g_slist_foreach (provider->methods, add_one_method, info);
+ info->parent_iter = country_iter;
+}
+
+static void
add_one_country (gpointer key, gpointer value, gpointer user_data)
{
GSList *providers = (GSList *) value;
MobilePopulateInfo *info = (MobilePopulateInfo *) user_data;
- GSList *iter;
- GtkTreeIter country_iter;
+ GtkTreeIter iter;
if (!provider_list_has_type (providers, info->provider_type))
return;
- gtk_tree_store_append (info->store, &country_iter, NULL);
- gtk_tree_store_set (info->store, &country_iter,
+ gtk_tree_store_append (info->store, &iter, NULL);
+ gtk_tree_store_set (info->store, &iter,
MOBILE_COL_NAME, key,
- MOBILE_COL_DATA, NULL,
-1);
- for (iter = providers; iter; iter = iter->next) {
- NmnMobileProvider *provider = (NmnMobileProvider *) iter->data;
- GtkTreeIter provider_iter;
-
- if (provider->type == info->provider_type) {
- gtk_tree_store_append (info->store, &provider_iter, &country_iter);
- gtk_tree_store_set (info->store, &provider_iter,
- MOBILE_COL_NAME, provider->name,
- MOBILE_COL_DATA, provider,
- -1);
- }
- }
+ info->parent_iter = &iter;
+ g_slist_foreach (providers, add_one_provider, info);
}
static void
@@ -212,11 +271,11 @@ mobile_list_populate (NmnNewConnection *connection)
if (priv->mobile_list_populated || !mobile_have_device (connection, &provider_type))
return;
- mobile_providers = nmn_mobile_providers_parse ();
+ mobile_providers = nmn_mobile_providers_parse (NULL);
if (!mobile_providers)
return;
- store = gtk_tree_store_new (2, G_TYPE_STRING, NMN_TYPE_MOBILE_PROVIDER);
+ store = gtk_tree_store_new (3, G_TYPE_STRING, NMN_TYPE_MOBILE_PROVIDER, NMN_TYPE_MOBILE_ACCESS_METHOD);
info.store = store;
info.provider_type = provider_type;
@@ -247,17 +306,18 @@ mobile_tree_selection_changed (GtkTreeSelection *selection,
NmnNewConnection *connection = (NmnNewConnection *) user_data;
NmnNewConnectionPrivate *priv = GET_PRIVATE (connection);
GtkTreeModel *model;
- NmnMobileProvider *provider = NULL;
+ NmnMobileAccessMethod *method = NULL;
GtkTreeIter iter;
if (gtk_tree_selection_get_selected (selection, &model, &iter))
- gtk_tree_model_get (model, &iter, MOBILE_COL_DATA, &provider, -1);
+ gtk_tree_model_get (model, &iter, MOBILE_COL_METHOD, &method, -1);
- gtk_widget_set_sensitive (priv->mobile_save, provider != NULL);
+ gtk_widget_set_sensitive (priv->mobile_save, method != NULL);
}
static NMConnection *
-mobile_new_connection (NmnMobileProvider *provider)
+mobile_new_connection (NmnMobileProvider *provider,
+ NmnMobileAccessMethod *method)
{
NMConnection *connection;
NMSetting *type_setting;
@@ -267,15 +327,28 @@ mobile_new_connection (NmnMobileProvider *provider)
connection = nm_connection_new ();
- if (provider->type == NMN_PROVIDER_TYPE_GSM) {
+ if (method->type == NMN_MOBILE_ACCESS_METHOD_TYPE_GSM) {
type_setting = nm_setting_gsm_new ();
g_object_set (type_setting,
- NM_SETTING_GSM_NUMBER, "*99#",
- NM_SETTING_GSM_USERNAME, provider->username,
- NM_SETTING_GSM_PASSWORD, provider->password,
- NM_SETTING_GSM_APN, provider->apn,
+ NM_SETTING_GSM_NUMBER, "*99#",
+ NM_SETTING_GSM_USERNAME, method->username,
+ NM_SETTING_GSM_PASSWORD, method->password,
+ NM_SETTING_GSM_APN, method->gsm_apn,
NULL);
- } else if (provider->type == NMN_PROVIDER_TYPE_CDMA) {
+
+ /* FIXME: Choose the network_id more intelligently */
+ if (g_slist_length (method->gsm_mcc_mnc) == 1) {
+ NmnGsmMccMnc *mcc_mnc = (NmnGsmMccMnc *) method->gsm_mcc_mnc->data;
+ char *network_id;
+
+ network_id = g_strconcat (mcc_mnc->mcc, mcc_mnc->mnc, NULL);
+ g_object_set (type_setting,
+ NM_SETTING_GSM_NETWORK_ID, network_id,
+ NULL);
+
+ g_free (network_id);
+ }
+ } else if (method->type == NMN_MOBILE_ACCESS_METHOD_TYPE_CDMA) {
type_setting = nm_setting_cdma_new ();
g_object_set (type_setting, NM_SETTING_CDMA_NUMBER, "#777", NULL);
} else
@@ -283,13 +356,13 @@ mobile_new_connection (NmnMobileProvider *provider)
nm_connection_add_setting (connection, type_setting);
- if (provider->gateway || provider->dns) {
+ if (method->gateway || method->dns) {
GSList *iter;
setting = nm_setting_ip4_config_new ();
g_object_set (setting, NM_SETTING_IP4_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, NULL);
- for (iter = provider->dns; iter; iter = iter->next) {
+ for (iter = method->dns; iter; iter = iter->next) {
struct in_addr addr;
if (inet_pton (AF_INET, (char *) iter->data, &addr) > 0)
@@ -297,8 +370,8 @@ mobile_new_connection (NmnMobileProvider *provider)
}
/* I'd rather not use the gateway from providers database */
- /* if (provider->gateway) */
-
+ /* if (method->gateway) */
+
nm_connection_add_setting (connection, setting);
}
@@ -333,7 +406,6 @@ mobile_new_connection (NmnMobileProvider *provider)
return connection;
}
-
static void
mobile_save_clicked (GtkButton *button, gpointer user_data)
{
@@ -342,17 +414,25 @@ mobile_save_clicked (GtkButton *button, gpointer user_data)
GtkTreeSelection *selection;
GtkTreeModel *model;
NmnMobileProvider *provider = NULL;
- GtkTreeIter iter;
+ NmnMobileAccessMethod *method = NULL;
+ GtkTreeIter method_iter;
+ GtkTreeIter provider_iter;
selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (priv->mobile_list));
- if (!gtk_tree_selection_get_selected (selection, &model, &iter))
+ if (!gtk_tree_selection_get_selected (selection, &model, &method_iter))
return;
- gtk_tree_model_get (model, &iter, MOBILE_COL_DATA, &provider, -1);
- if (provider) {
+ if (!gtk_tree_model_iter_parent (model, &provider_iter, &method_iter))
+ return;
+
+ gtk_tree_model_get (model, &method_iter, MOBILE_COL_METHOD, &method, -1);
+ gtk_tree_model_get (model, &provider_iter, MOBILE_COL_PROVIDER, &provider, -1);
+
+ if (provider && method) {
NMConnection *connection;
- connection = mobile_new_connection (provider);
+ connection = NULL;
+ connection = mobile_new_connection (provider, method);
nmn_mobile_provider_unref (provider);
if (connection) {
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]