Status area: add NetworkManager indicator
Adds an implementation of nm-applet in javascript. Uses the new introspection from NetworkManager, and temporarily requires nm-applet to be running for the secret service. Features a renewed interface, with each device controllable through a switch, which if toggled off disconnects, and if toggled on connects to the most recently used valid connection. More esoteric features like creation of ad-hoc networks have been moved to the control center panel. https://bugzilla.gnome.org/show_bug.cgi?id=621707
This commit is contained in:
parent
7f67c34b39
commit
c8ac3fd4f5
@ -153,6 +153,14 @@ StTooltip StLabel {
|
||||
spacing: .5em;
|
||||
}
|
||||
|
||||
.popup-inactive-menu-item {
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.popup-subtitle-menu-item {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.popup-menu-icon {
|
||||
icon-size: 1.14em;
|
||||
}
|
||||
|
@ -8,6 +8,7 @@ nobase_dist_js_DATA = \
|
||||
misc/format.js \
|
||||
misc/gnomeSession.js \
|
||||
misc/history.js \
|
||||
misc/modemManager.js \
|
||||
misc/params.js \
|
||||
misc/util.js \
|
||||
perf/core.js \
|
||||
@ -50,6 +51,7 @@ nobase_dist_js_DATA = \
|
||||
ui/statusMenu.js \
|
||||
ui/status/accessibility.js \
|
||||
ui/status/keyboard.js \
|
||||
ui/status/network.js \
|
||||
ui/status/power.js \
|
||||
ui/status/volume.js \
|
||||
ui/status/bluetooth.js \
|
||||
|
225
js/misc/modemManager.js
Normal file
225
js/misc/modemManager.js
Normal file
@ -0,0 +1,225 @@
|
||||
// -*- mode: js2; indent-tabs-mode: nil; js2-basic-offset: 4 -*-
|
||||
|
||||
const DBus = imports.dbus;
|
||||
const Lang = imports.lang;
|
||||
const Shell = imports.gi.Shell;
|
||||
const Signals = imports.signals;
|
||||
|
||||
// The following are not the complete interfaces, just the methods we need
|
||||
// (or may need in the future)
|
||||
|
||||
const ModemGsmNetworkInterface = {
|
||||
name: 'org.freedesktop.ModemManager.Modem.Gsm.Network',
|
||||
methods: [
|
||||
{ name: 'GetRegistrationInfo', inSignature: '', outSignature: 'uss' },
|
||||
{ name: 'GetSignalQuality', inSignature: '', outSignature: 'u' }
|
||||
],
|
||||
properties: [
|
||||
{ name: 'AccessTechnology', signature: 'u', access: 'read' }
|
||||
],
|
||||
signals: [
|
||||
{ name: 'SignalQuality', inSignature: 'u' },
|
||||
{ name: 'RegistrationInfo', inSignature: 'uss' }
|
||||
]
|
||||
};
|
||||
const ModemGsmNetworkProxy = DBus.makeProxyClass(ModemGsmNetworkInterface);
|
||||
|
||||
const ModemCdmaInterface = {
|
||||
name: 'org.freedesktop.ModemManager.Modem.Cdma',
|
||||
methods: [
|
||||
{ name: 'GetSignalQuality', inSignature: '', outSignature: 'u' },
|
||||
{ name: 'GetServingSystem', inSignature: '', outSignature: 'usu' }
|
||||
],
|
||||
signals: [
|
||||
{ name: 'SignalQuality', inSignature: 'u' }
|
||||
]
|
||||
};
|
||||
const ModemCdmaProxy = DBus.makeProxyClass(ModemCdmaInterface);
|
||||
|
||||
let _providersTable;
|
||||
function _getProvidersTable() {
|
||||
if (_providersTable)
|
||||
return _providersTable;
|
||||
let [providers, countryCodes] = Shell.mobile_providers_parse();
|
||||
return _providersTable = providers;
|
||||
}
|
||||
|
||||
function ModemGsm() {
|
||||
this._init.apply(this, arguments);
|
||||
}
|
||||
|
||||
ModemGsm.prototype = {
|
||||
_init: function(path) {
|
||||
this._proxy = new ModemGsmNetworkProxy(DBus.system, 'org.freedesktop.ModemManager', path);
|
||||
|
||||
this.signal_quality = 0;
|
||||
this.operator_name = null;
|
||||
|
||||
// Code is duplicated because the function have different signatures
|
||||
this._proxy.connect('SignalQuality', Lang.bind(this, function(proxy, quality) {
|
||||
this.signal_quality = quality;
|
||||
this.emit('notify::signal-quality');
|
||||
}));
|
||||
this._proxy.connect('RegistrationInfo', Lang.bind(this, function(proxy, status, code, name) {
|
||||
this.operator_name = this._findOperatorName(name, code);
|
||||
this.emit('notify::operator-name');
|
||||
}));
|
||||
this._proxy.GetRegistrationInfoRemote(Lang.bind(this, function(result, err) {
|
||||
if (err) {
|
||||
log(err);
|
||||
return;
|
||||
}
|
||||
|
||||
let [status, code, name] = result;
|
||||
this.operator_name = this._findOperatorName(name, code);
|
||||
this.emit('notify::operator-name');
|
||||
}));
|
||||
this._proxy.GetSignalQualityRemote(Lang.bind(this, function(result, err) {
|
||||
if (err) {
|
||||
// it will return an error if the device is not connected
|
||||
this.signal_quality = 0;
|
||||
} else {
|
||||
let [quality] = result;
|
||||
this.signal_quality = quality;
|
||||
}
|
||||
this.emit('notify::signal-quality');
|
||||
}));
|
||||
},
|
||||
|
||||
_findOperatorName: function(name, opCode) {
|
||||
if (name.length != 0 && (name.length > 6 || name.length < 5)) {
|
||||
// this looks like a valid name, i.e. not an MCCMNC (that some
|
||||
// devices return when not yet connected
|
||||
return name;
|
||||
}
|
||||
if (isNaN(parseInt(name))) {
|
||||
// name is definitely not a MCCMNC, so it may be a name
|
||||
// after all; return that
|
||||
return name;
|
||||
}
|
||||
|
||||
let needle;
|
||||
if (name.length == 0 && opCode)
|
||||
needle = opCode;
|
||||
else if (name.length == 6 || name.length == 5)
|
||||
needle = name;
|
||||
else // nothing to search
|
||||
return null;
|
||||
|
||||
return this._findProviderForMCCMNC(needle);
|
||||
},
|
||||
|
||||
_findProviderForMCCMNC: function(needle) {
|
||||
let table = _getProvidersTable();
|
||||
let needlemcc = needle.substring(0, 3);
|
||||
let needlemnc = needle.substring(3, needle.length);
|
||||
|
||||
let name2, name3;
|
||||
for (let iter in table) {
|
||||
let providers = table[iter];
|
||||
|
||||
// Search through each country's providers
|
||||
for (let i = 0; i < providers.length; i++) {
|
||||
let provider = providers[i];
|
||||
|
||||
// Search through MCC/MNC list
|
||||
let list = provider.get_gsm_mcc_mnc();
|
||||
for (let j = 0; j < list.length; j++) {
|
||||
let mccmnc = list[j];
|
||||
|
||||
// Match both 2-digit and 3-digit MNC; prefer a
|
||||
// 3-digit match if found, otherwise a 2-digit one.
|
||||
if (mccmnc.mcc != needlemcc)
|
||||
continue; // MCC was wrong
|
||||
|
||||
if (!name3 && needle.length == 6 && needlemnc == mccmnc.mnc)
|
||||
name3 = provider.name;
|
||||
|
||||
if (!name2 && needlemnc.substring(0, 2) == mccmnc.mnc.substring(0, 2))
|
||||
name2 = provider.name;
|
||||
|
||||
if (name2 && name3)
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return name3 || name2 || null;
|
||||
}
|
||||
}
|
||||
Signals.addSignalMethods(ModemGsm.prototype);
|
||||
|
||||
function ModemCdma() {
|
||||
this._init.apply(this, arguments);
|
||||
}
|
||||
|
||||
ModemCdma.prototype = {
|
||||
_init: function(path) {
|
||||
this._proxy = new ModemCdmaProxy(DBus.system, 'org.freedesktop.ModemManager', path);
|
||||
|
||||
this.signal_quality = 0;
|
||||
this.operator_name = null;
|
||||
this._proxy.connect('SignalQuality', Lang.bind(this, function(proxy, quality) {
|
||||
this.signal_quality = quality;
|
||||
this.emit('notify::signal-quality');
|
||||
|
||||
// receiving this signal means the device got activated
|
||||
// and we can finally call GetServingSystem
|
||||
if (this.operator_name == null)
|
||||
this._refreshServingSystem();
|
||||
}));
|
||||
this._proxy.GetSignalQualityRemote(Lang.bind(this, function(result, err) {
|
||||
if (err) {
|
||||
// it will return an error if the device is not connected
|
||||
this.signal_quality = 0;
|
||||
} else {
|
||||
let [quality] = result;
|
||||
this.signal_quality = quality;
|
||||
}
|
||||
this.emit('notify::signal-quality');
|
||||
}));
|
||||
},
|
||||
|
||||
_refreshServingSystem: function() {
|
||||
this._proxy.GetServingSystemRemote(Lang.bind(this, function(result, err) {
|
||||
if (err) {
|
||||
// it will return an error if the device is not connected
|
||||
this.operator_name = null;
|
||||
} else {
|
||||
let [bandClass, band, id] = result;
|
||||
if (name.length > 0)
|
||||
this.operator_name = this._findProviderForSid(id);
|
||||
else
|
||||
this.operator_name = null;
|
||||
}
|
||||
this.emit('notify::operator-name');
|
||||
}));
|
||||
},
|
||||
|
||||
_findProviderForSid: function(sid) {
|
||||
if (sid == 0)
|
||||
return null;
|
||||
|
||||
let table = _getProvidersTable();
|
||||
|
||||
// Search through each country
|
||||
for (let iter in table) {
|
||||
let providers = table[iter];
|
||||
|
||||
// Search through each country's providers
|
||||
for (let i = 0; i < providers.length; i++) {
|
||||
let provider = providers[i];
|
||||
let cdma_sid = provider.get_cdma_sid();
|
||||
|
||||
// Search through CDMA SID list
|
||||
for (let j = 0; j < cdma_sid.length; j++) {
|
||||
if (cdma_sid[j] == sid)
|
||||
return provider.name;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
};
|
||||
Signals.addSignalMethods(ModemCdma.prototype);
|
@ -178,3 +178,83 @@ function killall(processName) {
|
||||
logError(e, 'Failed to kill ' + processName);
|
||||
}
|
||||
}
|
||||
|
||||
// This was ported from network-manager-applet
|
||||
// Copyright 2007 - 2011 Red Hat, Inc.
|
||||
// Author: Dan Williams <dcbw@redhat.com>
|
||||
|
||||
const _IGNORED_WORDS = [
|
||||
'Semiconductor',
|
||||
'Components',
|
||||
'Corporation',
|
||||
'Communications',
|
||||
'Company',
|
||||
'Corp.',
|
||||
'Corp',
|
||||
'Co.',
|
||||
'Inc.',
|
||||
'Inc',
|
||||
'Incorporated',
|
||||
'Ltd.',
|
||||
'Limited.',
|
||||
'Intel?',
|
||||
'chipset',
|
||||
'adapter',
|
||||
'[hex]',
|
||||
'NDIS',
|
||||
'Module'
|
||||
];
|
||||
|
||||
const _IGNORED_PHRASES = [
|
||||
'Multiprotocol MAC/baseband processor',
|
||||
'Wireless LAN Controller',
|
||||
'Wireless LAN Adapter',
|
||||
'Wireless Adapter',
|
||||
'Network Connection',
|
||||
'Wireless Cardbus Adapter',
|
||||
'Wireless CardBus Adapter',
|
||||
'54 Mbps Wireless PC Card',
|
||||
'Wireless PC Card',
|
||||
'Wireless PC',
|
||||
'PC Card with XJACK(r) Antenna',
|
||||
'Wireless cardbus',
|
||||
'Wireless LAN PC Card',
|
||||
'Technology Group Ltd.',
|
||||
'Communication S.p.A.',
|
||||
'Business Mobile Networks BV',
|
||||
'Mobile Broadband Minicard Composite Device',
|
||||
'Mobile Communications AB',
|
||||
'(PC-Suite Mode)'
|
||||
];
|
||||
|
||||
function fixupPCIDescription(desc) {
|
||||
desc.replace(/[_,]/, ' ');
|
||||
|
||||
/* Attempt to shorten ID by ignoring certain phrases */
|
||||
for (let i = 0; i < _IGNORED_PHRASES.length; i++) {
|
||||
let item = _IGNORED_PHRASES[i];
|
||||
let pos = desc.indexOf(item);
|
||||
if (pos != -1) {
|
||||
let before = desc.substring(0, pos);
|
||||
let after = desc.substring(pos + item.length, desc.length);
|
||||
desc = before + after;
|
||||
}
|
||||
}
|
||||
|
||||
/* Attmept to shorten ID by ignoring certain individual words */
|
||||
let words = desc.split(' ');
|
||||
let out = [ ];
|
||||
for (let i = 0; i < words; i++) {
|
||||
let item = words[i];
|
||||
|
||||
// skip empty items (that come out from consecutive spaces)
|
||||
if (item.length == 0)
|
||||
continue;
|
||||
|
||||
if (_IGNORED_WORDS.indexOf(item) == -1) {
|
||||
out.push(item);
|
||||
}
|
||||
}
|
||||
|
||||
return out.join(' ');
|
||||
}
|
||||
|
@ -44,6 +44,12 @@ const STANDARD_TRAY_ICON_SHELL_IMPLEMENTATION = {
|
||||
if (Config.HAVE_BLUETOOTH)
|
||||
STANDARD_TRAY_ICON_SHELL_IMPLEMENTATION['bluetooth'] = imports.ui.status.bluetooth.Indicator;
|
||||
|
||||
try {
|
||||
STANDARD_TRAY_ICON_SHELL_IMPLEMENTATION['network'] = imports.ui.status.network.NMApplet;
|
||||
} catch(e) {
|
||||
log('NMApplet is not supported. It is possible that your NetworkManager version is too old');
|
||||
}
|
||||
|
||||
// To make sure the panel corners blend nicely with the panel,
|
||||
// we draw background and borders the same way, e.g. drawing
|
||||
// them as filled shapes from the outside inwards instead of
|
||||
|
2062
js/ui/status/network.js
Normal file
2062
js/ui/status/network.js
Normal file
File diff suppressed because it is too large
Load Diff
@ -20,6 +20,7 @@ js/ui/statusMenu.js
|
||||
js/ui/status/accessibility.js
|
||||
js/ui/status/bluetooth.js
|
||||
js/ui/status/keyboard.js
|
||||
js/ui/status/network.js
|
||||
js/ui/status/power.js
|
||||
js/ui/status/volume.js
|
||||
js/ui/telepathyClient.js
|
||||
@ -31,6 +32,7 @@ src/gdmuser/gdm-user.c
|
||||
src/main.c
|
||||
src/shell-app-system.c
|
||||
src/shell-global.c
|
||||
src/shell-mobile-providers.c
|
||||
src/shell-polkit-authentication-agent.c
|
||||
src/shell-util.c
|
||||
|
||||
|
@ -62,7 +62,8 @@ gnome_shell_cflags = \
|
||||
$(GNOME_SHELL_CFLAGS) \
|
||||
-I$(srcdir)/tray \
|
||||
-DVERSION=\"$(VERSION)\" \
|
||||
-DLOCALEDIR=\"$(datadir)/locale\" \
|
||||
-DLOCALEDIR=\"$(datadir)/locale\" \
|
||||
-DDATADIR=\"$(datadir)\" \
|
||||
-DGNOME_SHELL_LIBEXECDIR=\"$(libexecdir)\" \
|
||||
-DGNOME_SHELL_DATADIR=\"$(pkgdatadir)\" \
|
||||
-DGNOME_SHELL_PKGLIBDIR=\"$(pkglibdir)\" \
|
||||
@ -90,6 +91,7 @@ shell_public_headers_h = \
|
||||
shell-generic-container.h \
|
||||
shell-gtk-embed.h \
|
||||
shell-global.h \
|
||||
shell-mobile-providers.h \
|
||||
shell-perf-log.h \
|
||||
shell-slicer.h \
|
||||
shell-stack.h \
|
||||
@ -121,6 +123,7 @@ libgnome_shell_la_SOURCES = \
|
||||
shell-generic-container.c \
|
||||
shell-gtk-embed.c \
|
||||
shell-global.c \
|
||||
shell-mobile-providers.c \
|
||||
shell-perf-log.c \
|
||||
shell-polkit-authentication-agent.h \
|
||||
shell-polkit-authentication-agent.c \
|
||||
|
816
src/shell-mobile-providers.c
Normal file
816
src/shell-mobile-providers.c
Normal file
@ -0,0 +1,816 @@
|
||||
/* -*- 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 GHashTable *
|
||||
read_country_codes (void)
|
||||
{
|
||||
GHashTable *table;
|
||||
GIOChannel *channel;
|
||||
GString *buffer;
|
||||
GError *error = NULL;
|
||||
GIOStatus status;
|
||||
|
||||
channel = g_io_channel_new_file (ISO_3166_COUNTRY_CODES, "r", &error);
|
||||
if (!channel) {
|
||||
if (error) {
|
||||
g_warning ("Could not read " ISO_3166_COUNTRY_CODES ": %s", error->message);
|
||||
g_error_free (error);
|
||||
} else
|
||||
g_warning ("Could not read " ISO_3166_COUNTRY_CODES ": Unknown error");
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
table = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
|
||||
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] != '#') {
|
||||
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"));
|
||||
}
|
||||
|
||||
g_hash_table_insert (table, pieces[0], pieces[1]);
|
||||
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 *country_codes;
|
||||
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 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;
|
||||
char *country;
|
||||
|
||||
country_code = g_ascii_strup (attribute_values[i], -1);
|
||||
country = g_hash_table_lookup (parser->country_codes, country_code);
|
||||
if (country) {
|
||||
parser->current_country = g_strdup (country);
|
||||
g_free (country_code);
|
||||
} else
|
||||
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")) {
|
||||
g_hash_table_insert (parser->table, parser->current_country, 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:
|
||||
* @out_ccs: (out) (allow-none): (element-type utf8 utf8): a #GHashTable containing
|
||||
* country codes
|
||||
*
|
||||
* Returns: (element-type utf8 GList<Shell.MobileProvider>) (transfer container): a
|
||||
* hash table where keys are country names 'char *', values are a 'GSList *'
|
||||
* of 'ShellMobileProvider *'. Everything is destroyed with g_hash_table_destroy ().
|
||||
*/
|
||||
GHashTable *
|
||||
shell_mobile_providers_parse (GHashTable **out_ccs)
|
||||
{
|
||||
GMarkupParseContext *ctx;
|
||||
GIOChannel *channel;
|
||||
MobileParser parser;
|
||||
GError *error = NULL;
|
||||
char buffer[4096];
|
||||
GIOStatus status;
|
||||
gsize len = 0;
|
||||
|
||||
memset (&parser, 0, sizeof (MobileParser));
|
||||
|
||||
parser.country_codes = read_country_codes ();
|
||||
if (!parser.country_codes)
|
||||
goto out;
|
||||
|
||||
channel = g_io_channel_new_file (MOBILE_BROADBAND_PROVIDER_INFO, "r", &error);
|
||||
if (!channel) {
|
||||
if (error) {
|
||||
g_warning ("Could not read " MOBILE_BROADBAND_PROVIDER_INFO ": %s", error->message);
|
||||
g_error_free (error);
|
||||
} else
|
||||
g_warning ("Could not read " MOBILE_BROADBAND_PROVIDER_INFO ": Unknown error");
|
||||
|
||||
goto out;
|
||||
}
|
||||
|
||||
parser.table = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, provider_list_free);
|
||||
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:
|
||||
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 (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 *citer, *miter;
|
||||
|
||||
for (citer = value; 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 *providers)
|
||||
{
|
||||
g_return_if_fail (providers != NULL);
|
||||
g_hash_table_foreach (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;
|
||||
}
|
96
src/shell-mobile-providers.h
Normal file
96
src/shell-mobile-providers.h
Normal file
@ -0,0 +1,96 @@
|
||||
/* -*- 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;
|
||||
|
||||
|
||||
GType shell_gsm_mcc_mnc_get_type (void); /* added in porting */
|
||||
GType shell_mobile_provider_get_type (void);
|
||||
GType shell_mobile_access_method_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);
|
||||
|
||||
GHashTable *shell_mobile_providers_parse (GHashTable **out_ccs);
|
||||
|
||||
void shell_mobile_providers_dump (GHashTable *providers);
|
||||
|
||||
#endif /* SHELL_MOBILE_PROVIDERS_H */
|
Loading…
Reference in New Issue
Block a user