diff options
-rw-r--r-- | NetworkManager-r4060-use-modem-manager.patch (renamed from NetworkManager-r4027-use-modem-manager.patch) | 112 | ||||
-rw-r--r-- | nm-applet-r874-use-modem-manager.patch | 427 | ||||
-rw-r--r-- | nm-applet-r884-use-modem-manager.patch | 1524 |
3 files changed, 1620 insertions, 443 deletions
diff --git a/NetworkManager-r4027-use-modem-manager.patch b/NetworkManager-r4060-use-modem-manager.patch index 929d8419..bac492db 100644 --- a/NetworkManager-r4027-use-modem-manager.patch +++ b/NetworkManager-r4060-use-modem-manager.patch @@ -1,8 +1,8 @@ diff --git a/configure.in b/configure.in -index 9f7db7c..bee43d8 100644 +index bd86fc2..fdc4369 100644 --- a/configure.in +++ b/configure.in -@@ -444,6 +444,7 @@ src/dhcp-manager/Makefile +@@ -477,6 +477,7 @@ src/dhcp-manager/Makefile src/supplicant-manager/Makefile src/ppp-manager/Makefile src/dnsmasq-manager/Makefile @@ -890,10 +890,10 @@ index 0000000..9b16b0b +#endif /* NM_GSM_MODEM_HSO_H */ diff --git a/src/modem-manager/nm-gsm-modem.c b/src/modem-manager/nm-gsm-modem.c new file mode 100644 -index 0000000..0b75e6c +index 0000000..271e23f --- /dev/null +++ b/src/modem-manager/nm-gsm-modem.c -@@ -0,0 +1,316 @@ +@@ -0,0 +1,329 @@ +/* -*- Mode: C; tab-width: 5; indent-tabs-mode: t; c-basic-offset: 5 -*- */ + +#include <string.h> @@ -981,20 +981,33 @@ index 0000000..0b75e6c + dbus_g_proxy_end_call (proxy, call_id, &error, G_TYPE_INVALID); + + if (error) { -+ if (dbus_g_error_has_name (error, MM_MODEM_ERROR_PIN_NEEDED)) { ++ g_debug ("%s", dbus_g_error_get_name (error)); ++ ++ if (dbus_g_error_has_name (error, MM_MODEM_ERROR_SIM_PIN)) { + secret = setting->pin; + secret_name = NM_SETTING_GSM_PIN; + priv->modem_state = MODEM_STATE_SET_PIN; -+ } else if (dbus_g_error_has_name (error, MM_MODEM_ERROR_PUK_NEEDED)) { ++ } else if (dbus_g_error_has_name (error, MM_MODEM_ERROR_SIM_PUK)) { + secret = setting->puk; + secret_name = NM_SETTING_GSM_PUK; + priv->modem_state = MODEM_STATE_SET_PIN; -+ } else if (dbus_g_error_has_name (error, MM_MODEM_ERROR_INVALID_SECRET)) { ++ } else if (dbus_g_error_has_name (error, MM_MODEM_ERROR_SIM_WRONG)) { + g_free (setting->pin); + setting->pin = NULL; + secret_name = NM_SETTING_GSM_PIN; + retry_secret = TRUE; + priv->modem_state = MODEM_STATE_SET_PIN; ++ } ++ ++ /* FIXME: Hacks to ignore failures of setting band and network mode for now ++ since only Huawei module supports it. Remove when ModemManager rules. ++ */ ++ else if (dbus_g_error_has_name (error, MM_MODEM_ERROR_OPERATION_NOT_SUPPORTED) && ++ (priv->modem_state == MODEM_STATE_SET_BAND || ++ priv->modem_state == MODEM_STATE_SET_NETWORK_MODE)) { ++ ++ nm_warning ("Modem does not support setting %s, ignoring", ++ priv->modem_state == MODEM_STATE_SET_BAND ? "band" : "network mode"); + } else { + priv->modem_state = MODEM_STATE_FAILED; + nm_warning ("GSM modem connection failed: %s", error->message); @@ -1019,7 +1032,7 @@ index 0000000..0b75e6c + if (secret) { + priv->modem_state = MODEM_STATE_ENABLE; + dbus_g_proxy_begin_call (get_proxy (modem, MM_DBUS_INTERFACE_MODEM_GSM_CARD), -+ "SetPin", state_machine, ++ "SendPin", state_machine, + modem, NULL, + G_TYPE_STRING, secret, + G_TYPE_INVALID); @@ -1254,10 +1267,10 @@ index 0000000..8df8265 +#endif /* NM_GSM_MODEM_H */ diff --git a/src/modem-manager/nm-modem-device.c b/src/modem-manager/nm-modem-device.c new file mode 100644 -index 0000000..0a198f7 +index 0000000..c5ea8c6 --- /dev/null +++ b/src/modem-manager/nm-modem-device.c -@@ -0,0 +1,464 @@ +@@ -0,0 +1,467 @@ +/* -*- Mode: C; tab-width: 5; indent-tabs-mode: t; c-basic-offset: 5 -*- */ + +#include <string.h> @@ -1566,6 +1579,9 @@ index 0000000..0a198f7 + /* Make sure we don't leave the serial device open */ + switch (new_state) { + case NM_DEVICE_STATE_NEED_AUTH: ++ if (priv->ppp_manager) ++ break; ++ /* else fall through */ + case NM_DEVICE_STATE_UNMANAGED: + case NM_DEVICE_STATE_UNAVAILABLE: + case NM_DEVICE_STATE_FAILED: @@ -2230,10 +2246,10 @@ index 0000000..ec62f84 +#endif /* NM_MODEM_MANAGER_H */ diff --git a/src/modem-manager/nm-modem-types.h b/src/modem-manager/nm-modem-types.h new file mode 100644 -index 0000000..bd76796 +index 0000000..f5cbe10 --- /dev/null +++ b/src/modem-manager/nm-modem-types.h -@@ -0,0 +1,25 @@ +@@ -0,0 +1,89 @@ +/* -*- Mode: C; tab-width: 5; indent-tabs-mode: t; c-basic-offset: 5 -*- */ + +#ifndef NM_MODEM_TYPES_H @@ -2253,10 +2269,74 @@ index 0000000..bd76796 +#define MM_MODEM_TYPE_GSM 1 +#define MM_MODEM_TYPE_CDMA 2 + -+#define MM_MODEM_ERROR_GENERAL MM_DBUS_INTERFACE_MODEM ".GeneralError" -+#define MM_MODEM_ERROR_PIN_NEEDED MM_DBUS_INTERFACE_MODEM ".PINNeeded" -+#define MM_MODEM_ERROR_PUK_NEEDED MM_DBUS_INTERFACE_MODEM ".PUKNeeded" -+#define MM_MODEM_ERROR_INVALID_SECRET MM_DBUS_INTERFACE_MODEM ".InvalidSecret" ++/* Errors */ ++ ++#define MM_SERIAL_OPEN_FAILED MM_DBUS_INTERFACE_MODEM ".SerialOpenFailed" ++#define MM_SERIAL_SEND_FAILED MM_DBUS_INTERFACE_MODEM ".SerialSendFailed" ++#define MM_SERIAL_RESPONSE_TIMEOUT MM_DBUS_INTERFACE_MODEM ".SerialResponseTimeout" ++ ++#define MM_MODEM_ERROR_GENERAL MM_DBUS_INTERFACE_MODEM ".General" ++#define MM_MODEM_ERROR_OPERATION_NOT_SUPPORTED MM_DBUS_INTERFACE_MODEM ".OperationNotSupported" ++ ++#define MM_MODEM_CONNECT_ERROR_NO_CARRIER MM_DBUS_INTERFACE_MODEM ".NoCarrier" ++#define MM_MODEM_CONNECT_ERROR_NO_DIALTONE MM_DBUS_INTERFACE_MODEM ".NoDialtone" ++#define MM_MODEM_CONNECT_ERROR_BUSY MM_DBUS_INTERFACE_MODEM ".Busy" ++#define MM_MODEM_CONNECT_ERROR_NO_ANSWER MM_DBUS_INTERFACE_MODEM ".NoAnswer" ++ ++#define MM_MODEM_ERROR "org.freedesktop.ModemManager.Modem.Gsm" ++ ++#define MM_MODEM_ERROR_PHONE_FAILURE MM_MODEM_ERROR ".PhoneFailure" ++#define MM_MODEM_ERROR_NO_CONNECTION MM_MODEM_ERROR ".NoConnection" ++#define MM_MODEM_ERROR_LINK_RESERVED MM_MODEM_ERROR ".LinkReserved" ++#define MM_MODEM_ERROR_NOT_ALLOWED MM_MODEM_ERROR ".OperationNotAllowed" ++#define MM_MODEM_ERROR_NOT_SUPPORTED MM_MODEM_ERROR ".OperationNotSupported" ++#define MM_MODEM_ERROR_PH_SIM_PIN MM_MODEM_ERROR ".PhSimPinRequired" ++#define MM_MODEM_ERROR_PH_FSIM_PIN MM_MODEM_ERROR ".PhFSimPinRequired" ++#define MM_MODEM_ERROR_PH_FSIM_PUK MM_MODEM_ERROR ".PhFPukRequired" ++#define MM_MODEM_ERROR_SIM_NOT_INSERTED MM_MODEM_ERROR ".SimNotInserted" ++#define MM_MODEM_ERROR_SIM_PIN MM_MODEM_ERROR ".SimPinRequired" ++#define MM_MODEM_ERROR_SIM_PUK MM_MODEM_ERROR ".SimPukRequired" ++#define MM_MODEM_ERROR_SIM_FAILURE MM_MODEM_ERROR ".SimFailure" ++#define MM_MODEM_ERROR_SIM_BUSY MM_MODEM_ERROR ".SimBusy" ++#define MM_MODEM_ERROR_SIM_WRONG MM_MODEM_ERROR ".SimWrong" ++#define MM_MODEM_ERROR_WRONG_PASSWORD MM_MODEM_ERROR ".IncorrectPassword" ++#define MM_MODEM_ERROR_SIM_PIN2 MM_MODEM_ERROR ".SimPin2Required" ++#define MM_MODEM_ERROR_SIM_PUK2 MM_MODEM_ERROR ".SimPuk2Required" ++#define MM_MODEM_ERROR_MEMORY_FULL MM_MODEM_ERROR ".MemoryFull" ++#define MM_MODEM_ERROR_INVALID_INDEX MM_MODEM_ERROR ".InvalidIndex" ++#define MM_MODEM_ERROR_NOT_FOUND MM_MODEM_ERROR ".NotFound" ++#define MM_MODEM_ERROR_MEMORY_FAILURE MM_MODEM_ERROR ".MemoryFailure" ++#define MM_MODEM_ERROR_TEXT_TOO_LONG MM_MODEM_ERROR ".TextTooLong" ++#define MM_MODEM_ERROR_INVALID_CHARS MM_MODEM_ERROR ".InvalidChars" ++#define MM_MODEM_ERROR_DIAL_STRING_TOO_LONG MM_MODEM_ERROR ".DialStringTooLong" ++#define MM_MODEM_ERROR_DIAL_STRING_INVALID MM_MODEM_ERROR ".InvalidDialString" ++#define MM_MODEM_ERROR_NO_NETWORK MM_MODEM_ERROR ".NoNetwork" ++#define MM_MODEM_ERROR_NETWORK_TIMEOUT MM_MODEM_ERROR ".NetworkTimeout" ++#define MM_MODEM_ERROR_NETWORK_NOT_ALLOWED MM_MODEM_ERROR ".NetworkNotAllowed" ++#define MM_MODEM_ERROR_NETWORK_PIN MM_MODEM_ERROR ".NetworkPinRequired" ++#define MM_MODEM_ERROR_NETWORK_PUK MM_MODEM_ERROR ".NetworkPukRequired" ++#define MM_MODEM_ERROR_NETWORK_SUBSET_PIN MM_MODEM_ERROR ".NetworkSubsetPinRequired" ++#define MM_MODEM_ERROR_NETWORK_SUBSET_PUK MM_MODEM_ERROR ".NetworkSubsetPukRequired" ++#define MM_MODEM_ERROR_SERVICE_PIN MM_MODEM_ERROR ".ServicePinRequired" ++#define MM_MODEM_ERROR_SERVICE_PUK MM_MODEM_ERROR ".ServicePukRequired" ++#define MM_MODEM_ERROR_CORP_PIN MM_MODEM_ERROR ".CorporatePinRequired" ++#define MM_MODEM_ERROR_CORP_PUK MM_MODEM_ERROR ".CorporatePukRequired" ++#define MM_MODEM_ERROR_HIDDEN_KEY MM_MODEM_ERROR ".HiddenKeyRequired" ++#define MM_MODEM_ERROR_EAP_NOT_SUPPORTED MM_MODEM_ERROR ".EapMethodNotSupported" ++#define MM_MODEM_ERROR_INCORRECT_PARAMS MM_MODEM_ERROR ".IncorrectParams" ++#define MM_MODEM_ERROR_UNKNOWN MM_MODEM_ERROR ".Unknown" ++#define MM_MODEM_ERROR_GPRS_ILLEGAL_MS MM_MODEM_ERROR ".GprsIllegalMs" ++#define MM_MODEM_ERROR_GPRS_ILLEGAL_ME MM_MODEM_ERROR ".GprsIllegalMe" ++#define MM_MODEM_ERROR_GPRS_SERVICE_NOT_ALLOWED MM_MODEM_ERROR ".GprsServiceNotAllowed" ++#define MM_MODEM_ERROR_GPRS_PLMN_NOT_ALLOWED MM_MODEM_ERROR ".GprsPlmnNotAllowed" ++#define MM_MODEM_ERROR_GPRS_LOCATION_NOT_ALLOWED MM_MODEM_ERROR ".GprsLocationNotAllowed" ++#define MM_MODEM_ERROR_GPRS_ROAMING_NOT_ALLOWED MM_MODEM_ERROR ".GprsRoamingNotAllowed" ++#define MM_MODEM_ERROR_GPRS_OPTION_NOT_SUPPORTED MM_MODEM_ERROR ".GprsOptionNotSupported" ++#define MM_MODEM_ERROR_GPRS_NOT_SUBSCRIBED MM_MODEM_ERROR ".GprsNotSubscribed" ++#define MM_MODEM_ERROR_GPRS_OUT_OF_ORDER MM_MODEM_ERROR ".GprsOutOfOrder" ++#define MM_MODEM_ERROR_GPRS_PDP_AUTH_FAILURE MM_MODEM_ERROR ".GprsPdpAuthFailure" ++#define MM_MODEM_ERROR_GPRS_UNKNOWN MM_MODEM_ERROR ".GprsUnspecified" ++#define MM_MODEM_ERROR_GPRS_INVALID_CLASS MM_MODEM_ERROR ".GprsInvalidClass" + +#endif /* NM_MODEM_TYPES_H */ diff --git a/src/nm-cdma-device.c b/src/nm-cdma-device.c diff --git a/nm-applet-r874-use-modem-manager.patch b/nm-applet-r874-use-modem-manager.patch deleted file mode 100644 index 4d965461..00000000 --- a/nm-applet-r874-use-modem-manager.patch +++ /dev/null @@ -1,427 +0,0 @@ -diff --git a/src/Makefile.am b/src/Makefile.am -index de8ccb4..fe60b87 100644 ---- a/src/Makefile.am -+++ b/src/Makefile.am -@@ -49,6 +49,9 @@ nm_applet_SOURCES = \ - applet-device-gsm.c \ - applet-device-cdma.h \ - applet-device-cdma.c \ -+ mm-types.h \ -+ nma-gsm-modem.c \ -+ nma-gsm-modem.h \ - $(NULL) - - nm_applet_LDADD = \ -diff --git a/src/applet-device-gsm.c b/src/applet-device-gsm.c -index 1641661..fd2601d 100644 ---- a/src/applet-device-gsm.c -+++ b/src/applet-device-gsm.c -@@ -39,6 +39,8 @@ - - #include "applet.h" - #include "applet-device-gsm.h" -+#include "nma-gsm-modem.h" -+#include "mm-types.h" - #include "utils.h" - - typedef struct { -@@ -277,16 +279,64 @@ out: - } - - static void -+signal_quality_changed (NMAGsmModem *modem, guint32 quality, gpointer user_data) -+{ -+ applet_schedule_update_icon (NM_APPLET (user_data)); -+} -+ -+static void - gsm_device_state_changed (NMDevice *device, - NMDeviceState state, - NMApplet *applet) - { -- if (state == NM_DEVICE_STATE_ACTIVATED) { -- applet_do_notify (applet, NOTIFY_URGENCY_LOW, -- _("Connection Established"), -- _("You are now connected to the GSM network."), -- "nm-device-wwan", NULL, NULL, NULL, NULL); -+ NMAGsmModem *modem; -+ char *oper_code; -+ char *oper_name; -+ char *msg; -+ guint32 reg_status; -+ -+ if (state != NM_DEVICE_STATE_ACTIVATED) -+ return; -+ -+ modem = (NMAGsmModem *) g_object_get_data (G_OBJECT (device), "gsm-modem"); -+ if (!modem) { -+ DBusGConnection *bus; -+ -+ bus = dbus_g_bus_get (DBUS_BUS_SYSTEM, NULL); -+ if (!bus) -+ return; -+ -+ modem = nma_gsm_modem_new (bus, nm_device_get_udi (device)); -+ dbus_g_connection_unref (bus); -+ -+ g_object_set_data_full (G_OBJECT (device), "gsm-modem", modem, g_object_unref); -+ -+ g_signal_connect (modem, "signal-quality", -+ G_CALLBACK (signal_quality_changed), -+ applet); - } -+ -+ g_message ("Signal quality: %d", nma_gsm_modem_get_signal_quality (modem)); -+ g_message ("Network mode: %d", nma_gsm_modem_get_network_mode (modem)); -+ -+ oper_code = NULL; -+ oper_name = NULL; -+ -+ reg_status = nma_gsm_modem_get_registration_info (modem, &oper_code, &oper_name); -+ -+ g_message ("Reg status: %d code: %s name: %s", reg_status, oper_code, oper_name); -+ -+ msg = g_strdup_printf (_("You are now connected to the %s GSM network '%s'."), -+ reg_status == MM_GSM_MODEM_REG_STATUS_ROAMING ? _("roaming") : _("home"), -+ oper_name); -+ -+ applet_do_notify (applet, NOTIFY_URGENCY_LOW, -+ _("Connection Established"), msg, -+ "nm-device-wwan", NULL, NULL, NULL, NULL); -+ -+ g_free (oper_code); -+ g_free (oper_name); -+ g_free (msg); - } - - static GdkPixbuf * -@@ -295,6 +345,7 @@ gsm_get_icon (NMDevice *device, - char **tip, - NMApplet *applet) - { -+ NMAGsmModem *modem; - GdkPixbuf *pixbuf = NULL; - const char *iface; - -@@ -311,8 +362,40 @@ gsm_get_icon (NMDevice *device, - *tip = g_strdup_printf (_("Waiting for user authentication on device '%s'..."), iface); - break; - case NM_DEVICE_STATE_ACTIVATED: -- *tip = g_strdup (_("GSM connection")); -- pixbuf = applet->wwan_icon; -+ modem = (NMAGsmModem *) g_object_get_data (G_OBJECT (device), "gsm-modem"); -+ if (modem) { -+ char *oper_code; -+ char *oper_name; -+ guint32 reg_status; -+ guint32 quality; -+ -+ quality = nma_gsm_modem_get_signal_quality (modem); -+ quality = CLAMP (quality, 0, 100); -+ -+ if (quality > 80) -+ pixbuf = applet->wireless_100_icon; -+ else if (quality > 55) -+ pixbuf = applet->wireless_75_icon; -+ else if (quality > 30) -+ pixbuf = applet->wireless_50_icon; -+ else if (quality > 5) -+ pixbuf = applet->wireless_25_icon; -+ else -+ pixbuf = applet->wireless_00_icon; -+ -+ reg_status = nma_gsm_modem_get_registration_info (modem, &oper_code, &oper_name); -+ *tip = g_strdup_printf (_("%s GSM connection '%s' (%d%%)"), -+ reg_status == MM_GSM_MODEM_REG_STATUS_ROAMING ? _("Roaming") : _("Home"), -+ oper_name, quality); -+ -+ g_free (oper_name); -+ g_free (oper_code); -+ -+ } else { -+ pixbuf = applet->wireless_00_icon; -+ *tip = g_strdup_printf (_("GSM connection")); -+ } -+ - break; - default: - break; -diff --git a/src/mm-types.h b/src/mm-types.h -new file mode 100644 -index 0000000..a1f9979 ---- /dev/null -+++ b/src/mm-types.h -@@ -0,0 +1,18 @@ -+/* -*- Mode: C; tab-width: 5; indent-tabs-mode: t; c-basic-offset: 5 -*- */ -+ -+#ifndef MM_TYPES_H -+#define MM_TYPES_H -+ -+#define MM_DBUS_SERVICE "org.freedesktop.ModemManager" -+#define MM_DBUS_INTERFACE_MODEM_GSM "org.freedesktop.ModemManager.Modem.Gsm.Network" -+ -+enum { -+ MM_GSM_MODEM_REG_STATUS_IDLE = 0, -+ MM_GSM_MODEM_REG_STATUS_HOME = 1, -+ MM_GSM_MODEM_REG_STATUS_SEARCHING = 2, -+ MM_GSM_MODEM_REG_STATUS_DENIED = 3, -+ MM_GSM_MODEM_REG_STATUS_UNKNOWN = 4, -+ MM_GSM_MODEM_REG_STATUS_ROAMING = 5 -+}; -+ -+#endif /* MM_TYPES_H */ -diff --git a/src/nma-gsm-modem.c b/src/nma-gsm-modem.c -new file mode 100644 -index 0000000..584090b ---- /dev/null -+++ b/src/nma-gsm-modem.c -@@ -0,0 +1,198 @@ -+/* -*- Mode: C; tab-width: 5; indent-tabs-mode: t; c-basic-offset: 5 -*- */ -+ -+#include "nma-gsm-modem.h" -+#include "mm-types.h" -+ -+G_DEFINE_TYPE (NMAGsmModem, nma_gsm_modem, G_TYPE_OBJECT) -+ -+#define NMA_GSM_MODEM_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NMA_TYPE_GSM_MODEM, NMAGsmModemPrivate)) -+ -+typedef struct { -+ DBusGProxy *proxy; -+ int signal_quality; -+ -+ gboolean disposed; -+} NMAGsmModemPrivate; -+ -+enum { -+ SIGNAL_QUALITY, -+ NETWORK_MODE, -+ -+ LAST_SIGNAL -+}; -+ -+static guint signals[LAST_SIGNAL] = { 0 }; -+ -+static void -+signal_quality_proxy (DBusGProxy *proxy, -+ guint32 signal_quality, -+ gpointer user_data) -+{ -+ NMAGsmModem *modem = NMA_GSM_MODEM (user_data); -+ -+ NMA_GSM_MODEM_GET_PRIVATE (modem)->signal_quality = signal_quality; -+ -+ g_signal_emit (modem, signals[SIGNAL_QUALITY], 0, signal_quality); -+} -+ -+static void -+network_mode_proxy (DBusGProxy *proxy, -+ guint32 network_mode, -+ gpointer user_data) -+{ -+ NMAGsmModem *modem = NMA_GSM_MODEM (user_data); -+ -+ g_signal_emit (modem, signals[NETWORK_MODE], 0, network_mode); -+} -+ -+NMAGsmModem * -+nma_gsm_modem_new (DBusGConnection *bus, const char *object_path) -+{ -+ NMAGsmModem *modem; -+ NMAGsmModemPrivate *priv; -+ -+ g_return_val_if_fail (bus != NULL, NULL); -+ g_return_val_if_fail (object_path != NULL, NULL); -+ -+ modem = (NMAGsmModem *) g_object_new (NMA_TYPE_GSM_MODEM, NULL); -+ if (!modem) -+ return NULL; -+ -+ priv = NMA_GSM_MODEM_GET_PRIVATE (modem); -+ priv->proxy = dbus_g_proxy_new_for_name (bus, MM_DBUS_SERVICE, object_path, MM_DBUS_INTERFACE_MODEM_GSM); -+ -+ dbus_g_proxy_add_signal (priv->proxy, "SignalQuality", G_TYPE_UINT, G_TYPE_INVALID); -+ dbus_g_proxy_connect_signal (priv->proxy, "SignalQuality", -+ G_CALLBACK (signal_quality_proxy), -+ modem, -+ NULL); -+ -+ dbus_g_proxy_add_signal (priv->proxy, "NetworkMode", G_TYPE_UINT, G_TYPE_INVALID); -+ dbus_g_proxy_connect_signal (priv->proxy, "NetworkMode", -+ G_CALLBACK (network_mode_proxy), -+ modem, -+ NULL); -+ -+ return modem; -+} -+ -+guint32 -+nma_gsm_modem_get_signal_quality (NMAGsmModem *modem) -+{ -+ NMAGsmModemPrivate *priv = NMA_GSM_MODEM_GET_PRIVATE (modem); -+ GError *err = NULL; -+ -+ g_return_val_if_fail (NMA_IS_GSM_MODEM (modem), 0); -+ -+ if (priv->signal_quality == -1) { -+ if (dbus_g_proxy_call (priv->proxy, "GetSignalQuality", &err, -+ G_TYPE_INVALID, -+ G_TYPE_UINT, &priv->signal_quality, -+ G_TYPE_INVALID)) { -+ g_warning ("Error in getting signal quality: %s", err->message); -+ g_error_free (err); -+ } -+ } -+ -+ return priv->signal_quality; -+} -+ -+guint32 -+nma_gsm_modem_get_registration_info (NMAGsmModem *modem, -+ char **operator_code, -+ char **operator_name) -+{ -+ NMAGsmModemPrivate *priv = NMA_GSM_MODEM_GET_PRIVATE (modem); -+ GError *err = NULL; -+ guint32 status = MM_GSM_MODEM_REG_STATUS_UNKNOWN; -+ -+ g_return_val_if_fail (NMA_IS_GSM_MODEM (modem), 0); -+ -+ if (!dbus_g_proxy_call (priv->proxy, "GetRegistrationInfo", &err, -+ G_TYPE_INVALID, -+ G_TYPE_UINT, &status, -+ G_TYPE_STRING, operator_code, -+ G_TYPE_STRING, operator_name, -+ G_TYPE_INVALID)) { -+ g_warning ("Error in getting network mode: %s", err->message); -+ g_error_free (err); -+ } -+ -+ return status; -+} -+ -+guint32 -+nma_gsm_modem_get_network_mode (NMAGsmModem *modem) -+{ -+ NMAGsmModemPrivate *priv = NMA_GSM_MODEM_GET_PRIVATE (modem); -+ GError *err = NULL; -+ guint32 network_mode = 0; -+ -+ g_return_val_if_fail (NMA_IS_GSM_MODEM (modem), 0); -+ -+ if (!dbus_g_proxy_call (priv->proxy, "GetNetworkMode", &err, -+ G_TYPE_INVALID, -+ G_TYPE_UINT, &network_mode, -+ G_TYPE_INVALID)) { -+ g_warning ("Error in getting network mode: %s", err->message); -+ g_error_free (err); -+ } -+ -+ return network_mode; -+} -+ -+static void -+nma_gsm_modem_init (NMAGsmModem *modem) -+{ -+ NMAGsmModemPrivate *priv = NMA_GSM_MODEM_GET_PRIVATE (modem); -+ -+ priv->signal_quality = -1; -+} -+ -+static void -+dispose (GObject *object) -+{ -+ NMAGsmModemPrivate *priv = NMA_GSM_MODEM_GET_PRIVATE (object); -+ -+ if (priv->disposed) -+ return; -+ -+ priv->disposed = TRUE; -+ -+ if (priv->proxy) -+ g_object_unref (priv->proxy); -+ -+ G_OBJECT_CLASS (nma_gsm_modem_parent_class)->dispose (object); -+} -+ -+static void -+nma_gsm_modem_class_init (NMAGsmModemClass *modem_class) -+{ -+ GObjectClass *object_class = G_OBJECT_CLASS (modem_class); -+ -+ g_type_class_add_private (modem_class, sizeof (NMAGsmModemPrivate)); -+ -+ /* virtual methods */ -+ object_class->dispose = dispose; -+ -+ /* Signals */ -+ signals[SIGNAL_QUALITY] = -+ g_signal_new ("signal-quality", -+ G_OBJECT_CLASS_TYPE (object_class), -+ G_SIGNAL_RUN_FIRST, -+ G_STRUCT_OFFSET (NMAGsmModemClass, signal_quality), -+ NULL, NULL, -+ g_cclosure_marshal_VOID__UINT, -+ G_TYPE_NONE, 1, -+ G_TYPE_UINT); -+ -+ signals[NETWORK_MODE] = -+ g_signal_new ("network-mode", -+ G_OBJECT_CLASS_TYPE (object_class), -+ G_SIGNAL_RUN_FIRST, -+ G_STRUCT_OFFSET (NMAGsmModemClass, network_mode), -+ NULL, NULL, -+ g_cclosure_marshal_VOID__UINT, -+ G_TYPE_NONE, 1, -+ G_TYPE_UINT); -+} -diff --git a/src/nma-gsm-modem.h b/src/nma-gsm-modem.h -new file mode 100644 -index 0000000..90e7ae0 ---- /dev/null -+++ b/src/nma-gsm-modem.h -@@ -0,0 +1,45 @@ -+/* -*- Mode: C; tab-width: 5; indent-tabs-mode: t; c-basic-offset: 5 -*- */ -+ -+#ifndef NMA_GSM_MODEM_H -+#define NMA_GSM_MODEM_H -+ -+#include <glib/gtypes.h> -+#include <glib-object.h> -+#include <dbus/dbus-glib.h> -+ -+G_BEGIN_DECLS -+ -+#define NMA_TYPE_GSM_MODEM (nma_gsm_modem_get_type ()) -+#define NMA_GSM_MODEM(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NMA_TYPE_GSM_MODEM, NMAGsmModem)) -+#define NMA_GSM_MODEM_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NMA_TYPE_GSM_MODEM, NMAGsmModemClass)) -+#define NMA_IS_GSM_MODEM(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NMA_TYPE_GSM_MODEM)) -+#define NMA_IS_GSM_MODEM_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), NMA_TYPE_GSM_MODEM)) -+#define NMA_GSM_MODEM_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NMA_TYPE_GSM_MODEM, NMAGsmModemClass)) -+ -+typedef struct { -+ GObject parent; -+} NMAGsmModem; -+ -+typedef struct { -+ GObjectClass parent; -+ -+ /* Signals */ -+ void (*signal_quality) (NMAGsmModem *modem, guint32 signal_quality); -+ void (*network_mode) (NMAGsmModem *modem, guint32 network_mode); -+} NMAGsmModemClass; -+ -+GType nma_gsm_modem_get_type (void); -+ -+NMAGsmModem *nma_gsm_modem_new (DBusGConnection *bus, -+ const char *object_path); -+ -+guint32 nma_gsm_modem_get_signal_quality (NMAGsmModem *modem); -+guint32 nma_gsm_modem_get_registration_info (NMAGsmModem *modem, -+ char **operator_code, -+ char **operator_name); -+ -+guint32 nma_gsm_modem_get_network_mode (NMAGsmModem *modem); -+ -+G_END_DECLS -+ -+#endif /* NMA_GSM_MODEM_H */ diff --git a/nm-applet-r884-use-modem-manager.patch b/nm-applet-r884-use-modem-manager.patch new file mode 100644 index 00000000..7c141345 --- /dev/null +++ b/nm-applet-r884-use-modem-manager.patch @@ -0,0 +1,1524 @@ +diff --git a/configure.ac b/configure.ac +index 9e64b77..77ad2ac 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -221,6 +221,7 @@ src/utils/Makefile + src/gconf-helpers/Makefile + src/wireless-security/Makefile + src/connection-editor/Makefile ++src/modems/Makefile + icons/Makefile + po/Makefile.in + ]) +diff --git a/src/Makefile.am b/src/Makefile.am +index de8ccb4..2be2217 100644 +--- a/src/Makefile.am ++++ b/src/Makefile.am +@@ -1,4 +1,4 @@ +-SUBDIRS = marshallers utils gconf-helpers wireless-security connection-editor ++SUBDIRS = marshallers utils gconf-helpers wireless-security connection-editor modems + + NULL= + +@@ -49,6 +49,9 @@ nm_applet_SOURCES = \ + applet-device-gsm.c \ + applet-device-cdma.h \ + applet-device-cdma.c \ ++ mm-types.h \ ++ nma-gsm-modem.c \ ++ nma-gsm-modem.h \ + $(NULL) + + nm_applet_LDADD = \ +diff --git a/src/applet-device-gsm.c b/src/applet-device-gsm.c +index 1641661..f0a31e6 100644 +--- a/src/applet-device-gsm.c ++++ b/src/applet-device-gsm.c +@@ -24,6 +24,9 @@ + #include <config.h> + #endif + ++#include <sys/types.h> ++#include <unistd.h> ++ + #include <glib/gi18n.h> + #include <gtk/gtkwidget.h> + #include <gtk/gtkmenuitem.h> +@@ -39,6 +42,8 @@ + + #include "applet.h" + #include "applet-device-gsm.h" ++#include "nma-gsm-modem.h" ++#include "mm-types.h" + #include "utils.h" + + typedef struct { +@@ -165,6 +170,50 @@ add_default_connection_item (NMDevice *device, + } + + static void ++child_setup (gpointer user_data G_GNUC_UNUSED) ++{ ++ /* We are in the child process at this point */ ++ pid_t pid = getpid (); ++ setpgid (pid, pid); ++} ++ ++static void ++gsm_properties_cb (GtkMenuItem *mi, gpointer user_data) ++{ ++ NMDevice *device = NM_DEVICE (user_data); ++ char *argv[3]; ++ GError *error = NULL; ++ gboolean success; ++ ++ argv[0] = BINDIR "/nm-modem-properties"; ++ argv[1] = (char *) nm_device_get_udi (device); ++ argv[2] = NULL; ++ ++ success = g_spawn_async ("/", argv, NULL, 0, &child_setup, NULL, NULL, &error); ++ if (!success) { ++ g_warning ("Error launching modem properties dialog: %s", error->message); ++ g_error_free (error); ++ } ++} ++ ++static void ++add_properties_item (NMDevice *device, ++ GtkWidget *menu) ++{ ++ GtkWidget *item; ++ ++ if (nm_device_get_state (device) != NM_DEVICE_STATE_DISCONNECTED) ++ return; ++ ++ item = gtk_menu_item_new_with_label (_("Properties")); ++ g_signal_connect (item, "activate", ++ G_CALLBACK (gsm_properties_cb), ++ device); ++ ++ gtk_menu_shell_append (GTK_MENU_SHELL (menu), item); ++} ++ ++static void + gsm_menu_item_deactivate (GtkMenuItem *item, gpointer user_data) + { + GSMMenuItemInfo *info = (GSMMenuItemInfo *) user_data; +@@ -270,23 +319,66 @@ gsm_add_menu_item (NMDevice *device, + add_connection_items (device, connections, active, menu, applet); + else + add_default_connection_item (device, menu, applet); ++ + add_disconnect_item (device, menu, applet); ++ add_properties_item (device, menu); + + out: + g_slist_free (connections); + } + + static void ++signal_quality_changed (NMAGsmModem *modem, guint32 quality, gpointer user_data) ++{ ++ applet_schedule_update_icon (NM_APPLET (user_data)); ++} ++ ++static void + gsm_device_state_changed (NMDevice *device, + NMDeviceState state, + NMApplet *applet) + { +- if (state == NM_DEVICE_STATE_ACTIVATED) { +- applet_do_notify (applet, NOTIFY_URGENCY_LOW, +- _("Connection Established"), +- _("You are now connected to the GSM network."), +- "nm-device-wwan", NULL, NULL, NULL, NULL); ++ NMAGsmModem *modem; ++ char *oper_code; ++ char *oper_name; ++ char *msg; ++ guint32 reg_status; ++ ++ if (state != NM_DEVICE_STATE_ACTIVATED) ++ return; ++ ++ modem = (NMAGsmModem *) g_object_get_data (G_OBJECT (device), "gsm-modem"); ++ if (!modem) { ++ DBusGConnection *bus; ++ ++ bus = dbus_g_bus_get (DBUS_BUS_SYSTEM, NULL); ++ if (!bus) ++ return; ++ ++ modem = nma_gsm_modem_new (bus, nm_device_get_udi (device)); ++ dbus_g_connection_unref (bus); ++ ++ g_object_set_data_full (G_OBJECT (device), "gsm-modem", modem, g_object_unref); ++ ++ g_signal_connect (modem, "signal-quality", ++ G_CALLBACK (signal_quality_changed), ++ applet); + } ++ ++ oper_code = NULL; ++ oper_name = NULL; ++ reg_status = nma_gsm_modem_get_registration_info (modem, &oper_code, &oper_name); ++ msg = g_strdup_printf (_("You are now connected to the %s GSM network '%s'."), ++ reg_status == MM_GSM_MODEM_REG_STATUS_ROAMING ? _("roaming") : _("home"), ++ oper_name); ++ ++ applet_do_notify (applet, NOTIFY_URGENCY_LOW, ++ _("Connection Established"), msg, ++ "nm-device-wwan", NULL, NULL, NULL, NULL); ++ ++ g_free (oper_code); ++ g_free (oper_name); ++ g_free (msg); + } + + static GdkPixbuf * +@@ -295,6 +387,7 @@ gsm_get_icon (NMDevice *device, + char **tip, + NMApplet *applet) + { ++ NMAGsmModem *modem; + GdkPixbuf *pixbuf = NULL; + const char *iface; + +@@ -311,8 +404,40 @@ gsm_get_icon (NMDevice *device, + *tip = g_strdup_printf (_("Waiting for user authentication on device '%s'..."), iface); + break; + case NM_DEVICE_STATE_ACTIVATED: +- *tip = g_strdup (_("GSM connection")); +- pixbuf = applet->wwan_icon; ++ modem = (NMAGsmModem *) g_object_get_data (G_OBJECT (device), "gsm-modem"); ++ if (modem) { ++ char *oper_code; ++ char *oper_name; ++ guint32 reg_status; ++ guint32 quality; ++ ++ quality = nma_gsm_modem_get_signal_quality (modem); ++ quality = CLAMP (quality, 0, 100); ++ ++ if (quality > 80) ++ pixbuf = applet->wireless_100_icon; ++ else if (quality > 55) ++ pixbuf = applet->wireless_75_icon; ++ else if (quality > 30) ++ pixbuf = applet->wireless_50_icon; ++ else if (quality > 5) ++ pixbuf = applet->wireless_25_icon; ++ else ++ pixbuf = applet->wireless_00_icon; ++ ++ reg_status = nma_gsm_modem_get_registration_info (modem, &oper_code, &oper_name); ++ *tip = g_strdup_printf (_("%s GSM connection '%s' (%d%%)"), ++ reg_status == MM_GSM_MODEM_REG_STATUS_ROAMING ? _("Roaming") : _("Home"), ++ oper_name, quality); ++ ++ g_free (oper_name); ++ g_free (oper_code); ++ ++ } else { ++ pixbuf = applet->wireless_00_icon; ++ *tip = g_strdup_printf (_("GSM connection")); ++ } ++ + break; + default: + break; +diff --git a/src/mm-types.h b/src/mm-types.h +new file mode 100644 +index 0000000..a1f9979 +--- /dev/null ++++ b/src/mm-types.h +@@ -0,0 +1,18 @@ ++/* -*- Mode: C; tab-width: 5; indent-tabs-mode: t; c-basic-offset: 5 -*- */ ++ ++#ifndef MM_TYPES_H ++#define MM_TYPES_H ++ ++#define MM_DBUS_SERVICE "org.freedesktop.ModemManager" ++#define MM_DBUS_INTERFACE_MODEM_GSM "org.freedesktop.ModemManager.Modem.Gsm.Network" ++ ++enum { ++ MM_GSM_MODEM_REG_STATUS_IDLE = 0, ++ MM_GSM_MODEM_REG_STATUS_HOME = 1, ++ MM_GSM_MODEM_REG_STATUS_SEARCHING = 2, ++ MM_GSM_MODEM_REG_STATUS_DENIED = 3, ++ MM_GSM_MODEM_REG_STATUS_UNKNOWN = 4, ++ MM_GSM_MODEM_REG_STATUS_ROAMING = 5 ++}; ++ ++#endif /* MM_TYPES_H */ +diff --git a/src/modems/Makefile.am b/src/modems/Makefile.am +new file mode 100644 +index 0000000..206ee52 +--- /dev/null ++++ b/src/modems/Makefile.am +@@ -0,0 +1,25 @@ ++bin_PROGRAMS = nm-modem-properties ++ ++nm_modem_properties_CPPFLAGS = \ ++ $(NMA_CFLAGS) \ ++ -DICONDIR=\""$(datadir)/icons"\" \ ++ -DGLADEDIR=\""$(gladedir)"\" \ ++ -DBINDIR=\""$(bindir)"\" \ ++ -DSYSCONFDIR=\""$(sysconfdir)"\" \ ++ -DLIBDIR=\""$(libdir)"\" \ ++ -DNMALOCALEDIR=\"$(datadir)/locale\" \ ++ $(DBUS_CFLAGS) \ ++ -I${top_srcdir}/src/gconf-helpers ++ ++nm_modem_properties_SOURCES = \ ++ main.c ++ ++nm_modem_properties_LDADD = \ ++ $(top_builddir)/src/gconf-helpers/libgconf-helpers.la \ ++ $(NMA_LIBS) ++ ++gladedir = $(datadir)/nm-applet ++glade_DATA = nm-modem-properties.glade ++ ++CLEANFILES = *.bak *.gladep ++EXTRA_DIST = $(glade_DATA) +diff --git a/src/modems/main.c b/src/modems/main.c +new file mode 100644 +index 0000000..27e700c +--- /dev/null ++++ b/src/modems/main.c +@@ -0,0 +1,592 @@ ++/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ ++ ++#include <string.h> ++#include <gtk/gtk.h> ++#include <glade/glade.h> ++#include <dbus/dbus-glib.h> ++#include <gconf/gconf-client.h> ++#include <nm-connection.h> ++#include <nm-setting-connection.h> ++#include <nm-setting-gsm.h> ++#include <nm-setting-serial.h> ++#include <nm-setting-ppp.h> ++#include <nm-utils.h> ++#include "gconf-helpers.h" ++ ++#define MM_DBUS_SERVICE "org.freedesktop.ModemManager" ++#define MM_DBUS_PATH "/org/freedesktop/ModemManager" ++#define MM_DBUS_INTERFACE "org.freedesktop.ModemManager" ++#define MM_DBUS_INTERFACE_MODEM "org.freedesktop.ModemManager.Modem" ++ ++#define MM_DBUS_INTERFACE_MODEM_GSM_CARD "org.freedesktop.ModemManager.Modem.Gsm.Card" ++#define MM_DBUS_INTERFACE_MODEM_GSM_NETWORK "org.freedesktop.ModemManager.Modem.Gsm.Network" ++ ++#define MM_MODEM_TYPE_UNKNOWN 0 ++#define MM_MODEM_TYPE_GSM 1 ++#define MM_MODEM_TYPE_CDMA 2 ++ ++#define SCAN_COL_NAME 0 ++#define SCAN_COL_STATUS 1 ++#define SCAN_COL_OPER_ID 2 ++ ++typedef struct { ++ /* UI */ ++ GladeXML *glade_xml; ++ GtkDialog *main_dialog; ++ GtkTable *info_table; ++ GtkTreeView *network_list; ++ GtkListStore *network_store; ++ GtkWidget *scan_button; ++ GtkWidget *create_net_button; ++ GtkLabel *signal_quality_label; ++ ++ GtkDialog *create_network_dialog; ++ GtkEntry *create_network_name; ++ ++ /* DBus */ ++ DBusGConnection *bus; ++ DBusGProxy *proxy; ++ DBusGProxy *gsm_net_proxy; ++ ++ GMainLoop *main_loop; ++} AppData; ++ ++ ++typedef struct { ++ GtkTable *table; ++ char *label; ++ guint row; ++} InfoData; ++ ++static InfoData * ++info_data_new (GtkTable *table, const char *label, guint row) ++{ ++ InfoData *info; ++ ++ info = g_slice_new (InfoData); ++ info->table = table; ++ info->label = g_strdup (label); ++ info->row = row; ++ ++ return info; ++} ++ ++static void ++info_data_free (gpointer data) ++{ ++ InfoData *info = (InfoData *) data; ++ ++ g_free (info->label); ++ g_slice_free (InfoData, data); ++} ++ ++static void ++add_info_row (GtkTable *table, guint row, const char *label, const char *value) ++{ ++ GtkWidget *w; ++ ++ w = gtk_label_new (label); ++ gtk_misc_set_alignment (GTK_MISC (w), 0.0, 0.0); ++ gtk_widget_show (w); ++ gtk_table_attach_defaults (table, w, 0, 1, row, row + 1); ++ ++ w = gtk_label_new (value); ++ gtk_misc_set_alignment (GTK_MISC (w), 0.0, 0.0); ++ gtk_widget_show (w); ++ gtk_table_attach_defaults (table, w, 1, 2, row, row + 1); ++} ++ ++static void ++get_str_done (DBusGProxy *proxy, DBusGProxyCall *call_id, gpointer user_data) ++{ ++ InfoData *info = (InfoData *) user_data; ++ char *result = NULL; ++ GError *error = NULL; ++ ++ if (!dbus_g_proxy_end_call (proxy, call_id, &error, G_TYPE_STRING, &result, G_TYPE_INVALID)) { ++ g_warning ("Couldn't get %s: %s", info->label, error->message); ++ g_error_free (error); ++ } else { ++ add_info_row (info->table, info->row, info->label, result); ++ g_free (result); ++ } ++} ++ ++static void ++get_card_info_done (DBusGProxy *proxy, DBusGProxyCall *call_id, gpointer user_data) ++{ ++ GtkTable *table = GTK_TABLE (user_data); ++ char *manufacturer = NULL; ++ char *model = NULL; ++ char *version = NULL; ++ GError *error = NULL; ++ ++ if (!dbus_g_proxy_end_call (proxy, call_id, &error, ++ G_TYPE_STRING, &manufacturer, ++ G_TYPE_STRING, &model, ++ G_TYPE_STRING, &version, ++ G_TYPE_INVALID)) { ++ g_warning ("Couldn't get modem information: %s", error->message); ++ g_error_free (error); ++ } else { ++ add_info_row (table, 0, "Vendor", manufacturer); ++ g_free (manufacturer); ++ ++ add_info_row (table, 1, "Model", model); ++ g_free (model); ++ ++ add_info_row (table, 2, "Version", version); ++ g_free (version); ++ } ++} ++ ++static void ++get_property_done (DBusGProxy *proxy, DBusGProxyCall *call_id, gpointer user_data) ++{ ++ InfoData *info = (InfoData *) user_data; ++ GValue value = { 0, }; ++ GError *error = NULL; ++ ++ if (!dbus_g_proxy_end_call (proxy, call_id, &error, G_TYPE_VALUE, &value, G_TYPE_INVALID)) { ++ g_warning ("Couldn't get %s: %s", info->label, error->message); ++ g_error_free (error); ++ } else { ++ add_info_row (info->table, info->row, info->label, g_value_get_string (&value)); ++ g_value_unset (&value); ++ } ++} ++ ++static gboolean ++get_info (gpointer data) ++{ ++ AppData *app_data = (AppData *) data; ++ ++ dbus_g_proxy_set_interface (app_data->proxy, MM_DBUS_INTERFACE_MODEM_GSM_CARD); ++ dbus_g_proxy_begin_call (app_data->proxy, "GetImsi", get_str_done, ++ info_data_new (app_data->info_table, "IMSI", 5), info_data_free, ++ G_TYPE_INVALID); ++ ++ dbus_g_proxy_begin_call (app_data->proxy, "GetImei", get_str_done, ++ info_data_new (app_data->info_table, "IMEI", 6), info_data_free, ++ G_TYPE_INVALID); ++ ++ dbus_g_proxy_begin_call (app_data->proxy, "GetInfo", get_card_info_done, ++ app_data->info_table, NULL, ++ G_TYPE_INVALID); ++ ++ dbus_g_proxy_set_interface (app_data->proxy, "org.freedesktop.DBus.Properties"); ++ ++ dbus_g_proxy_begin_call (app_data->proxy, "Get", get_property_done, ++ info_data_new (app_data->info_table, "Driver", 3), info_data_free, ++ G_TYPE_STRING, MM_DBUS_INTERFACE_MODEM, ++ G_TYPE_STRING, "Driver", ++ G_TYPE_INVALID); ++ ++ dbus_g_proxy_begin_call (app_data->proxy, "Get", get_property_done, ++ info_data_new (app_data->info_table, "Data device", 4), info_data_free, ++ G_TYPE_STRING, MM_DBUS_INTERFACE_MODEM, ++ G_TYPE_STRING, "DataDevice", ++ G_TYPE_INVALID); ++ ++ return FALSE; ++} ++ ++static void ++got_signal_quality (DBusGProxy *proxy, DBusGProxyCall *call_id, gpointer user_data) ++{ ++ AppData *app_data = (AppData *) user_data; ++ guint32 quality = 0; ++ GError *error = NULL; ++ ++ if (!dbus_g_proxy_end_call (proxy, call_id, &error, G_TYPE_UINT, &quality, G_TYPE_INVALID)) { ++ g_warning ("Couldn't get signal quality: %s", error->message); ++ g_error_free (error); ++ } else { ++ char *tmp; ++ ++ tmp = g_strdup_printf ("%d%%", quality); ++ gtk_label_set_text (app_data->signal_quality_label, tmp); ++ g_free (tmp); ++ } ++} ++ ++static void ++signal_quality_changed (DBusGProxy *proxy, ++ guint32 signal_quality, ++ gpointer user_data) ++{ ++ AppData *app_data = (AppData *) user_data; ++ char *tmp; ++ ++ tmp = g_strdup_printf ("%d%%", signal_quality); ++ gtk_label_set_text (app_data->signal_quality_label, tmp); ++ g_free (tmp); ++} ++ ++static gboolean ++monitor_signal_quality (gpointer data) ++{ ++ AppData *app_data = (AppData *) data; ++ GtkWidget *w; ++ ++ w = gtk_label_new ("Signal Quality"); ++ gtk_misc_set_alignment (GTK_MISC (w), 0.0, 0.0); ++ gtk_widget_show (w); ++ gtk_table_attach_defaults (app_data->info_table, w, 0, 1, 7, 8); ++ ++ w = gtk_label_new (""); ++ gtk_misc_set_alignment (GTK_MISC (w), 0.0, 0.0); ++ gtk_widget_show (w); ++ gtk_table_attach_defaults (app_data->info_table, w, 1, 2, 7, 8); ++ app_data->signal_quality_label = GTK_LABEL (w); ++ ++ dbus_g_proxy_add_signal (app_data->gsm_net_proxy, "SignalQuality", G_TYPE_UINT, G_TYPE_INVALID); ++ dbus_g_proxy_connect_signal (app_data->gsm_net_proxy, "SignalQuality", ++ G_CALLBACK (signal_quality_changed), ++ app_data, ++ NULL); ++ ++ dbus_g_proxy_begin_call (app_data->gsm_net_proxy, "GetSignalQuality", got_signal_quality, ++ app_data, NULL, ++ G_TYPE_INVALID); ++ ++ return FALSE; ++} ++ ++static void ++got_scan_results (DBusGProxy *proxy, DBusGProxyCall *call_id, gpointer user_data) ++{ ++ AppData *app_data = (AppData *) user_data; ++ GPtrArray *array = NULL; ++ GError *error = NULL; ++ GType type; ++ ++ type = dbus_g_type_get_collection ("GPtrArray", DBUS_TYPE_G_STRING_STRING_HASHTABLE); ++ ++ if (!dbus_g_proxy_end_call (proxy, call_id, &error, type, &array, G_TYPE_INVALID)) { ++ g_warning ("Couldn't scan: %s", error->message); ++ g_error_free (error); ++ } else { ++ GtkTreeIter iter; ++ int i; ++ ++ for (i = 0; i < array->len; i++) { ++ GHashTable *hash = (GHashTable *) g_ptr_array_index (array, i); ++ char *status; ++ const char *status_str; ++ ++ status = g_hash_table_lookup (hash, "status"); ++ if (!strcmp (status, "1")) ++ status_str = "Available"; ++ else if (!strcmp (status, "2")) ++ status_str = "Current"; ++ else if (!strcmp (status, "3")) ++ status_str = "Forbidden"; ++ else ++ status_str = "Unknown"; ++ ++ gtk_list_store_append (app_data->network_store, &iter); ++ gtk_list_store_set (app_data->network_store, &iter, ++ SCAN_COL_NAME, g_hash_table_lookup (hash, "operator-long"), ++ SCAN_COL_STATUS, status_str, ++ SCAN_COL_OPER_ID, g_hash_table_lookup (hash, "operator-num"), ++ -1); ++ ++ g_hash_table_destroy (hash); ++ } ++ ++ g_ptr_array_free (array, TRUE); ++ } ++ ++ gtk_widget_set_sensitive (app_data->scan_button, TRUE); ++} ++ ++static void ++scan (GtkButton *button, gpointer user_data) ++{ ++ AppData *app_data = (AppData *) user_data; ++ ++ dbus_g_proxy_begin_call (app_data->gsm_net_proxy, "Scan", got_scan_results, ++ app_data, NULL, ++ G_TYPE_INVALID); ++ ++ gtk_widget_set_sensitive (app_data->scan_button, FALSE); ++ gtk_list_store_clear (app_data->network_store); ++ /* FIXME: Add "Scanning..." dialog */ ++} ++ ++static void ++modem_enabled (DBusGProxy *proxy, DBusGProxyCall *call_id, gpointer user_data) ++{ ++ AppData *app_data = (AppData *) user_data; ++ GError *error = NULL; ++ ++ if (!dbus_g_proxy_end_call (proxy, call_id, &error, G_TYPE_INVALID)) { ++ g_warning ("Couldn't enable modem: %s", error->message); ++ g_error_free (error); ++ g_main_loop_quit (app_data->main_loop); ++ return; ++ } ++ ++ g_idle_add (get_info, app_data); ++ g_idle_add (monitor_signal_quality, app_data); ++} ++ ++static void ++modem_enable (AppData *app_data) ++{ ++ dbus_g_proxy_begin_call (app_data->proxy, "Enable", modem_enabled, ++ app_data, NULL, ++ G_TYPE_BOOLEAN, TRUE, G_TYPE_INVALID); ++} ++ ++static void ++create_network (const char *name, const char *oper_code) ++{ ++ NMConnection *connection; ++ NMSettingGsm *s_gsm; ++ NMSettingSerial *s_serial; ++ NMSettingPPP *s_ppp; ++ NMSettingConnection *s_con; ++ GConfClient *gconf_client; ++ ++ connection = nm_connection_new (); ++ ++ s_gsm = NM_SETTING_GSM (nm_setting_gsm_new ()); ++ s_gsm->number = g_strdup ("*99#"); /* This should be a sensible default as it's seems to be quite standard */ ++ s_gsm->network_id = g_strdup (oper_code); ++ nm_connection_add_setting (connection, NM_SETTING (s_gsm)); ++ ++ /* Serial setting */ ++ s_serial = (NMSettingSerial *) nm_setting_serial_new (); ++ s_serial->baud = 115200; ++ s_serial->bits = 8; ++ s_serial->parity = 'n'; ++ s_serial->stopbits = 1; ++ nm_connection_add_setting (connection, NM_SETTING (s_serial)); ++ ++ s_ppp = (NMSettingPPP *) nm_setting_ppp_new (); ++ nm_connection_add_setting (connection, NM_SETTING (s_ppp)); ++ ++ s_con = NM_SETTING_CONNECTION (nm_setting_connection_new ()); ++ s_con->id = g_strdup (name); ++ s_con->type = g_strdup (NM_SETTING (s_gsm)->name); ++ s_con->autoconnect = FALSE; ++ s_con->uuid = nm_utils_uuid_generate (); ++ nm_connection_add_setting (connection, NM_SETTING (s_con)); ++ ++ gconf_client = gconf_client_get_default (); ++ if (gconf_client) { ++ char *dir = NULL; ++ int i; ++ ++ /* Find free GConf directory */ ++ for (i = 0; i < G_MAXUINT32; i++) { ++ char buf[255]; ++ ++ snprintf (&buf[0], 255, GCONF_PATH_CONNECTIONS"/%d", i); ++ if (!gconf_client_dir_exists (gconf_client, buf, NULL)) { ++ dir = g_strdup (buf); ++ break; ++ } ++ } ++ ++ nm_gconf_write_connection (connection, gconf_client, dir); ++ gconf_client_notify (gconf_client, dir); ++ gconf_client_suggest_sync (gconf_client, NULL); ++ g_free (dir); ++ g_object_unref (gconf_client); ++ } else ++ g_warning ("Writing conneciton failed"); ++ ++ g_object_unref (connection); ++} ++ ++static void ++create_network_clicked (GtkButton *button, gpointer user_data) ++{ ++ AppData *app_data = (AppData *) user_data; ++ GtkTreeSelection *selection; ++ GList *selected_rows; ++ GtkTreeModel *model = NULL; ++ GtkTreeIter iter; ++ ++ selection = gtk_tree_view_get_selection (app_data->network_list); ++ selected_rows = gtk_tree_selection_get_selected_rows (selection, &model); ++ if (!selected_rows) ++ return; ++ ++ if (gtk_tree_model_get_iter (model, &iter, (GtkTreePath *) selected_rows->data)) { ++ char *oper_name = NULL; ++ char *oper_id = NULL; ++ gint result; ++ ++ gtk_tree_model_get (model, &iter, SCAN_COL_NAME, &oper_name, -1); ++ gtk_tree_model_get (model, &iter, SCAN_COL_OPER_ID, &oper_id, -1); ++ ++ gtk_entry_set_text (app_data->create_network_name, oper_name); ++ gtk_editable_select_region (GTK_EDITABLE (app_data->create_network_name), 0, -1); ++ gtk_widget_grab_focus (GTK_WIDGET (app_data->create_network_name)); ++ ++ result = gtk_dialog_run (app_data->create_network_dialog); ++ gtk_widget_hide (GTK_WIDGET (app_data->create_network_dialog)); ++ ++ if (result == GTK_RESPONSE_OK) ++ create_network (gtk_entry_get_text (app_data->create_network_name), oper_id); ++ ++ g_free (oper_name); ++ g_free (oper_id); ++ } ++ ++ /* free memory */ ++ g_list_foreach (selected_rows, (GFunc) gtk_tree_path_free, NULL); ++ g_list_free (selected_rows); ++} ++ ++static void ++network_list_selection_changed (GtkTreeSelection *selection, gpointer user_data) ++{ ++ AppData *app_data = (AppData *) user_data; ++ GtkTreeIter iter; ++ GtkTreeModel *model; ++ ++ if (gtk_tree_selection_get_selected (selection, &model, &iter)) ++ gtk_widget_set_sensitive (app_data->create_net_button, TRUE); ++ else ++ gtk_widget_set_sensitive (app_data->create_net_button, FALSE); ++} ++ ++ ++static void ++app_data_destroy (AppData *app_data) ++{ ++ if (app_data->bus) ++ dbus_g_connection_unref (app_data->bus); ++ ++ if (app_data->proxy) ++ g_object_unref (app_data->proxy); ++ ++ if (app_data->gsm_net_proxy) ++ g_object_unref (app_data->gsm_net_proxy); ++ ++ if (app_data->glade_xml) ++ g_object_unref (app_data->glade_xml); ++ ++ if (app_data->main_loop) ++ g_main_loop_unref (app_data->main_loop); ++ ++ g_slice_free (AppData, app_data); ++} ++ ++static void ++close_cb (GtkDialog *dialog, ++ gint response_id, ++ gpointer user_data) ++{ ++ AppData *app_data = (AppData *) user_data; ++ ++ dbus_g_proxy_set_interface (app_data->proxy, MM_DBUS_INTERFACE_MODEM); ++ dbus_g_proxy_call_no_reply (app_data->proxy, "Enable", G_TYPE_BOOLEAN, FALSE, G_TYPE_INVALID); ++ ++ g_main_loop_quit (app_data->main_loop); ++ app_data_destroy (app_data); ++} ++ ++ ++static GtkListStore * ++prepare_network_list (GtkTreeView *treeview) ++{ ++ GtkListStore *store; ++ ++ store = gtk_list_store_new (3, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING); ++ gtk_tree_view_set_model (treeview, GTK_TREE_MODEL (store)); ++ g_object_unref (store); ++ ++ gtk_tree_view_insert_column_with_attributes (treeview, ++ -1, "Name", gtk_cell_renderer_text_new (), ++ "text", SCAN_COL_NAME, ++ NULL); ++ ++ gtk_tree_view_insert_column_with_attributes (treeview, ++ -1, "Status", gtk_cell_renderer_text_new (), ++ "text", SCAN_COL_STATUS, ++ NULL); ++ ++ return store; ++} ++ ++static AppData * ++app_data_create (const char *udi) ++{ ++ AppData *app_data; ++ GtkTreeSelection *selection; ++ GError *error = NULL; ++ ++ app_data = g_slice_new0 (AppData); ++ ++ /* DBus */ ++ app_data->bus = dbus_g_bus_get (DBUS_BUS_SYSTEM, &error); ++ if (!app_data->bus) { ++ g_error ("Couldn't connect to DBus: %s", error->message); ++ g_error_free (error); ++ g_slice_free (AppData, app_data); ++ ++ return NULL; ++ } ++ ++ app_data->proxy = dbus_g_proxy_new_for_name (app_data->bus, MM_DBUS_SERVICE, udi, MM_DBUS_INTERFACE_MODEM); ++ app_data->gsm_net_proxy = dbus_g_proxy_new_from_proxy (app_data->proxy, MM_DBUS_INTERFACE_MODEM_GSM_NETWORK, NULL); ++ ++ /* UI */ ++ app_data->glade_xml = glade_xml_new (GLADEDIR "/nm-modem-properties.glade", NULL, NULL); ++ if (!app_data->glade_xml) { ++ g_error ("Could not load Glade file"); ++ g_slice_free (AppData, app_data); ++ ++ return NULL; ++ } ++ ++ app_data->main_dialog = GTK_DIALOG (glade_xml_get_widget (app_data->glade_xml, "dialog")); ++ g_signal_connect (app_data->main_dialog, "response", G_CALLBACK (close_cb), app_data); ++ ++ app_data->info_table = GTK_TABLE (glade_xml_get_widget (app_data->glade_xml, "info_table")); ++ app_data->network_list = GTK_TREE_VIEW (glade_xml_get_widget (app_data->glade_xml, "network_list")); ++ app_data->network_store = prepare_network_list (app_data->network_list); ++ app_data->scan_button = glade_xml_get_widget (app_data->glade_xml, "scan_button"); ++ g_signal_connect (app_data->scan_button, "clicked", G_CALLBACK (scan), app_data); ++ ++ app_data->create_net_button = glade_xml_get_widget (app_data->glade_xml, "create_connection_button"); ++ gtk_widget_set_sensitive (app_data->create_net_button, FALSE); ++ g_signal_connect (app_data->create_net_button, "clicked", G_CALLBACK (create_network_clicked), app_data); ++ selection = gtk_tree_view_get_selection (app_data->network_list); ++ g_signal_connect (selection, "changed", G_CALLBACK (network_list_selection_changed), app_data); ++ ++ app_data->create_network_dialog = GTK_DIALOG (glade_xml_get_widget (app_data->glade_xml, "create_network_dialog")); ++ app_data->create_network_name = GTK_ENTRY (glade_xml_get_widget (app_data->glade_xml, "create_network_name")); ++ ++ app_data->main_loop = g_main_loop_new (NULL, FALSE); ++ ++ return app_data; ++} ++ ++int ++main (int argc, char *argv[]) ++{ ++ //const char *udi = "/org/freedesktop/Hal/devices/usb_device_12d1_1003_noserial_if0_serial_usb_0"; ++ AppData *app_data; ++ ++ if (argc != 2) { ++ g_print ("Usage: %s <udi>\n", argv[0]); ++ return 1; ++ } ++ ++ gtk_init (&argc, &argv); ++ ++ app_data = app_data_create (argv[1]); ++ if (app_data) { ++ modem_enable (app_data); ++ g_main_loop_run (app_data->main_loop); ++ } ++ ++ return 0; ++} +diff --git a/src/modems/nm-modem-properties.glade b/src/modems/nm-modem-properties.glade +new file mode 100644 +index 0000000..61038b8 +--- /dev/null ++++ b/src/modems/nm-modem-properties.glade +@@ -0,0 +1,381 @@ ++<?xml version="1.0" standalone="no"?> <!--*- mode: xml -*--> ++<!DOCTYPE glade-interface SYSTEM "http://glade.gnome.org/glade-2.0.dtd"> ++ ++<glade-interface> ++ ++<widget class="GtkDialog" id="dialog"> ++ <property name="visible">True</property> ++ <property name="title" translatable="yes">GSM modem properties</property> ++ <property name="type">GTK_WINDOW_TOPLEVEL</property> ++ <property name="window_position">GTK_WIN_POS_NONE</property> ++ <property name="modal">False</property> ++ <property name="resizable">True</property> ++ <property name="destroy_with_parent">False</property> ++ <property name="decorated">True</property> ++ <property name="skip_taskbar_hint">False</property> ++ <property name="skip_pager_hint">False</property> ++ <property name="type_hint">GDK_WINDOW_TYPE_HINT_DIALOG</property> ++ <property name="gravity">GDK_GRAVITY_NORTH_WEST</property> ++ <property name="focus_on_map">True</property> ++ <property name="urgency_hint">False</property> ++ <property name="has_separator">True</property> ++ ++ <child internal-child="vbox"> ++ <widget class="GtkVBox" id="dialog-vbox1"> ++ <property name="visible">True</property> ++ <property name="homogeneous">False</property> ++ <property name="spacing">0</property> ++ ++ <child internal-child="action_area"> ++ <widget class="GtkHButtonBox" id="dialog-action_area1"> ++ <property name="visible">True</property> ++ <property name="layout_style">GTK_BUTTONBOX_END</property> ++ ++ <child> ++ <widget class="GtkButton" id="closebutton1"> ++ <property name="visible">True</property> ++ <property name="can_default">True</property> ++ <property name="can_focus">True</property> ++ <property name="label">gtk-close</property> ++ <property name="use_stock">True</property> ++ <property name="relief">GTK_RELIEF_NORMAL</property> ++ <property name="focus_on_click">True</property> ++ <property name="response_id">-7</property> ++ </widget> ++ </child> ++ </widget> ++ <packing> ++ <property name="padding">0</property> ++ <property name="expand">False</property> ++ <property name="fill">True</property> ++ <property name="pack_type">GTK_PACK_END</property> ++ </packing> ++ </child> ++ ++ <child> ++ <widget class="GtkVBox" id="vbox1"> ++ <property name="visible">True</property> ++ <property name="homogeneous">False</property> ++ <property name="spacing">6</property> ++ ++ <child> ++ <widget class="GtkFrame" id="frame1"> ++ <property name="visible">True</property> ++ <property name="label_xalign">0</property> ++ <property name="label_yalign">0.5</property> ++ <property name="shadow_type">GTK_SHADOW_NONE</property> ++ ++ <child> ++ <widget class="GtkAlignment" id="alignment1"> ++ <property name="visible">True</property> ++ <property name="xalign">0.5</property> ++ <property name="yalign">0.5</property> ++ <property name="xscale">1</property> ++ <property name="yscale">1</property> ++ <property name="top_padding">0</property> ++ <property name="bottom_padding">0</property> ++ <property name="left_padding">12</property> ++ <property name="right_padding">0</property> ++ ++ <child> ++ <widget class="GtkTable" id="info_table"> ++ <property name="visible">True</property> ++ <property name="n_rows">8</property> ++ <property name="n_columns">2</property> ++ <property name="homogeneous">False</property> ++ <property name="row_spacing">0</property> ++ <property name="column_spacing">6</property> ++ </widget> ++ </child> ++ </widget> ++ </child> ++ ++ <child> ++ <widget class="GtkLabel" id="label1"> ++ <property name="visible">True</property> ++ <property name="label" translatable="yes"><b>Information</b></property> ++ <property name="use_underline">False</property> ++ <property name="use_markup">True</property> ++ <property name="justify">GTK_JUSTIFY_LEFT</property> ++ <property name="wrap">False</property> ++ <property name="selectable">False</property> ++ <property name="xalign">0.5</property> ++ <property name="yalign">0.5</property> ++ <property name="xpad">0</property> ++ <property name="ypad">0</property> ++ <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property> ++ <property name="width_chars">-1</property> ++ <property name="single_line_mode">False</property> ++ <property name="angle">0</property> ++ </widget> ++ <packing> ++ <property name="type">label_item</property> ++ </packing> ++ </child> ++ </widget> ++ <packing> ++ <property name="padding">0</property> ++ <property name="expand">True</property> ++ <property name="fill">True</property> ++ </packing> ++ </child> ++ ++ <child> ++ <widget class="GtkFrame" id="frame2"> ++ <property name="visible">True</property> ++ <property name="label_xalign">0</property> ++ <property name="label_yalign">0.5</property> ++ <property name="shadow_type">GTK_SHADOW_NONE</property> ++ ++ <child> ++ <widget class="GtkAlignment" id="alignment2"> ++ <property name="visible">True</property> ++ <property name="xalign">0.5</property> ++ <property name="yalign">0.5</property> ++ <property name="xscale">1</property> ++ <property name="yscale">1</property> ++ <property name="top_padding">0</property> ++ <property name="bottom_padding">0</property> ++ <property name="left_padding">12</property> ++ <property name="right_padding">0</property> ++ ++ <child> ++ <widget class="GtkHBox" id="hbox1"> ++ <property name="visible">True</property> ++ <property name="homogeneous">False</property> ++ <property name="spacing">6</property> ++ ++ <child> ++ <widget class="GtkScrolledWindow" id="scrolledwindow1"> ++ <property name="visible">True</property> ++ <property name="can_focus">True</property> ++ <property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property> ++ <property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property> ++ <property name="shadow_type">GTK_SHADOW_IN</property> ++ <property name="window_placement">GTK_CORNER_TOP_LEFT</property> ++ ++ <child> ++ <widget class="GtkTreeView" id="network_list"> ++ <property name="visible">True</property> ++ <property name="can_focus">True</property> ++ <property name="headers_visible">False</property> ++ <property name="rules_hint">False</property> ++ <property name="reorderable">False</property> ++ <property name="enable_search">True</property> ++ <property name="fixed_height_mode">False</property> ++ <property name="hover_selection">False</property> ++ <property name="hover_expand">False</property> ++ </widget> ++ </child> ++ </widget> ++ <packing> ++ <property name="padding">0</property> ++ <property name="expand">True</property> ++ <property name="fill">True</property> ++ </packing> ++ </child> ++ ++ <child> ++ <widget class="GtkVButtonBox" id="vbuttonbox1"> ++ <property name="visible">True</property> ++ <property name="layout_style">GTK_BUTTONBOX_START</property> ++ <property name="spacing">0</property> ++ ++ <child> ++ <widget class="GtkButton" id="scan_button"> ++ <property name="visible">True</property> ++ <property name="can_default">True</property> ++ <property name="can_focus">True</property> ++ <property name="label" translatable="yes">Scan</property> ++ <property name="use_underline">True</property> ++ <property name="relief">GTK_RELIEF_NORMAL</property> ++ <property name="focus_on_click">True</property> ++ </widget> ++ </child> ++ ++ <child> ++ <widget class="GtkButton" id="create_connection_button"> ++ <property name="visible">True</property> ++ <property name="can_default">True</property> ++ <property name="can_focus">True</property> ++ <property name="label" translatable="yes">Create connection</property> ++ <property name="use_underline">True</property> ++ <property name="relief">GTK_RELIEF_NORMAL</property> ++ <property name="focus_on_click">True</property> ++ </widget> ++ </child> ++ </widget> ++ <packing> ++ <property name="padding">0</property> ++ <property name="expand">False</property> ++ <property name="fill">False</property> ++ </packing> ++ </child> ++ </widget> ++ </child> ++ </widget> ++ </child> ++ ++ <child> ++ <widget class="GtkLabel" id="label2"> ++ <property name="visible">True</property> ++ <property name="label" translatable="yes"><b>Networks</b></property> ++ <property name="use_underline">False</property> ++ <property name="use_markup">True</property> ++ <property name="justify">GTK_JUSTIFY_LEFT</property> ++ <property name="wrap">False</property> ++ <property name="selectable">False</property> ++ <property name="xalign">0.5</property> ++ <property name="yalign">0.5</property> ++ <property name="xpad">0</property> ++ <property name="ypad">0</property> ++ <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property> ++ <property name="width_chars">-1</property> ++ <property name="single_line_mode">False</property> ++ <property name="angle">0</property> ++ </widget> ++ <packing> ++ <property name="type">label_item</property> ++ </packing> ++ </child> ++ </widget> ++ <packing> ++ <property name="padding">0</property> ++ <property name="expand">True</property> ++ <property name="fill">True</property> ++ </packing> ++ </child> ++ </widget> ++ <packing> ++ <property name="padding">0</property> ++ <property name="expand">True</property> ++ <property name="fill">True</property> ++ </packing> ++ </child> ++ </widget> ++ </child> ++</widget> ++ ++<widget class="GtkDialog" id="create_network_dialog"> ++ <property name="title" translatable="yes">Create new connection</property> ++ <property name="type">GTK_WINDOW_TOPLEVEL</property> ++ <property name="window_position">GTK_WIN_POS_NONE</property> ++ <property name="modal">False</property> ++ <property name="resizable">False</property> ++ <property name="destroy_with_parent">False</property> ++ <property name="decorated">True</property> ++ <property name="skip_taskbar_hint">False</property> ++ <property name="skip_pager_hint">False</property> ++ <property name="type_hint">GDK_WINDOW_TYPE_HINT_DIALOG</property> ++ <property name="gravity">GDK_GRAVITY_NORTH_WEST</property> ++ <property name="focus_on_map">True</property> ++ <property name="urgency_hint">False</property> ++ <property name="has_separator">True</property> ++ ++ <child internal-child="vbox"> ++ <widget class="GtkVBox" id="dialog-vbox2"> ++ <property name="visible">True</property> ++ <property name="homogeneous">False</property> ++ <property name="spacing">0</property> ++ ++ <child internal-child="action_area"> ++ <widget class="GtkHButtonBox" id="dialog-action_area2"> ++ <property name="visible">True</property> ++ <property name="layout_style">GTK_BUTTONBOX_END</property> ++ ++ <child> ++ <widget class="GtkButton" id="cancelbutton1"> ++ <property name="visible">True</property> ++ <property name="can_default">True</property> ++ <property name="can_focus">True</property> ++ <property name="label">gtk-cancel</property> ++ <property name="use_stock">True</property> ++ <property name="relief">GTK_RELIEF_NORMAL</property> ++ <property name="focus_on_click">True</property> ++ <property name="response_id">-6</property> ++ </widget> ++ </child> ++ ++ <child> ++ <widget class="GtkButton" id="okbutton1"> ++ <property name="visible">True</property> ++ <property name="can_default">True</property> ++ <property name="can_focus">True</property> ++ <property name="label">gtk-ok</property> ++ <property name="use_stock">True</property> ++ <property name="relief">GTK_RELIEF_NORMAL</property> ++ <property name="focus_on_click">True</property> ++ <property name="response_id">-5</property> ++ </widget> ++ </child> ++ </widget> ++ <packing> ++ <property name="padding">0</property> ++ <property name="expand">False</property> ++ <property name="fill">True</property> ++ <property name="pack_type">GTK_PACK_END</property> ++ </packing> ++ </child> ++ ++ <child> ++ <widget class="GtkVBox" id="vbox2"> ++ <property name="border_width">6</property> ++ <property name="visible">True</property> ++ <property name="homogeneous">False</property> ++ <property name="spacing">6</property> ++ ++ <child> ++ <widget class="GtkLabel" id="label3"> ++ <property name="visible">True</property> ++ <property name="label" translatable="yes">Please choose a name for the connection</property> ++ <property name="use_underline">False</property> ++ <property name="use_markup">False</property> ++ <property name="justify">GTK_JUSTIFY_LEFT</property> ++ <property name="wrap">False</property> ++ <property name="selectable">False</property> ++ <property name="xalign">0.5</property> ++ <property name="yalign">0.5</property> ++ <property name="xpad">0</property> ++ <property name="ypad">0</property> ++ <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property> ++ <property name="width_chars">-1</property> ++ <property name="single_line_mode">False</property> ++ <property name="angle">0</property> ++ </widget> ++ <packing> ++ <property name="padding">0</property> ++ <property name="expand">False</property> ++ <property name="fill">False</property> ++ </packing> ++ </child> ++ ++ <child> ++ <widget class="GtkEntry" id="create_network_name"> ++ <property name="visible">True</property> ++ <property name="can_focus">True</property> ++ <property name="editable">True</property> ++ <property name="visibility">True</property> ++ <property name="max_length">0</property> ++ <property name="text" translatable="yes"></property> ++ <property name="has_frame">True</property> ++ <property name="invisible_char">●</property> ++ <property name="activates_default">True</property> ++ </widget> ++ <packing> ++ <property name="padding">0</property> ++ <property name="expand">False</property> ++ <property name="fill">False</property> ++ </packing> ++ </child> ++ </widget> ++ <packing> ++ <property name="padding">0</property> ++ <property name="expand">True</property> ++ <property name="fill">True</property> ++ </packing> ++ </child> ++ </widget> ++ </child> ++</widget> ++ ++</glade-interface> +diff --git a/src/nma-gsm-modem.c b/src/nma-gsm-modem.c +new file mode 100644 +index 0000000..0dba9cd +--- /dev/null ++++ b/src/nma-gsm-modem.c +@@ -0,0 +1,198 @@ ++/* -*- Mode: C; tab-width: 5; indent-tabs-mode: t; c-basic-offset: 5 -*- */ ++ ++#include "nma-gsm-modem.h" ++#include "mm-types.h" ++ ++G_DEFINE_TYPE (NMAGsmModem, nma_gsm_modem, G_TYPE_OBJECT) ++ ++#define NMA_GSM_MODEM_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NMA_TYPE_GSM_MODEM, NMAGsmModemPrivate)) ++ ++typedef struct { ++ DBusGProxy *proxy; ++ int signal_quality; ++ ++ gboolean disposed; ++} NMAGsmModemPrivate; ++ ++enum { ++ SIGNAL_QUALITY, ++ NETWORK_MODE, ++ ++ LAST_SIGNAL ++}; ++ ++static guint signals[LAST_SIGNAL] = { 0 }; ++ ++static void ++signal_quality_proxy (DBusGProxy *proxy, ++ guint32 signal_quality, ++ gpointer user_data) ++{ ++ NMAGsmModem *modem = NMA_GSM_MODEM (user_data); ++ ++ NMA_GSM_MODEM_GET_PRIVATE (modem)->signal_quality = signal_quality; ++ ++ g_signal_emit (modem, signals[SIGNAL_QUALITY], 0, signal_quality); ++} ++ ++static void ++network_mode_proxy (DBusGProxy *proxy, ++ guint32 network_mode, ++ gpointer user_data) ++{ ++ NMAGsmModem *modem = NMA_GSM_MODEM (user_data); ++ ++ g_signal_emit (modem, signals[NETWORK_MODE], 0, network_mode); ++} ++ ++NMAGsmModem * ++nma_gsm_modem_new (DBusGConnection *bus, const char *object_path) ++{ ++ NMAGsmModem *modem; ++ NMAGsmModemPrivate *priv; ++ ++ g_return_val_if_fail (bus != NULL, NULL); ++ g_return_val_if_fail (object_path != NULL, NULL); ++ ++ modem = (NMAGsmModem *) g_object_new (NMA_TYPE_GSM_MODEM, NULL); ++ if (!modem) ++ return NULL; ++ ++ priv = NMA_GSM_MODEM_GET_PRIVATE (modem); ++ priv->proxy = dbus_g_proxy_new_for_name (bus, MM_DBUS_SERVICE, object_path, MM_DBUS_INTERFACE_MODEM_GSM); ++ ++ dbus_g_proxy_add_signal (priv->proxy, "SignalQuality", G_TYPE_UINT, G_TYPE_INVALID); ++ dbus_g_proxy_connect_signal (priv->proxy, "SignalQuality", ++ G_CALLBACK (signal_quality_proxy), ++ modem, ++ NULL); ++ ++ dbus_g_proxy_add_signal (priv->proxy, "NetworkMode", G_TYPE_UINT, G_TYPE_INVALID); ++ dbus_g_proxy_connect_signal (priv->proxy, "NetworkMode", ++ G_CALLBACK (network_mode_proxy), ++ modem, ++ NULL); ++ ++ return modem; ++} ++ ++guint32 ++nma_gsm_modem_get_signal_quality (NMAGsmModem *modem) ++{ ++ NMAGsmModemPrivate *priv = NMA_GSM_MODEM_GET_PRIVATE (modem); ++ GError *err = NULL; ++ ++ g_return_val_if_fail (NMA_IS_GSM_MODEM (modem), 0); ++ ++ if (priv->signal_quality == -1) { ++ if (!dbus_g_proxy_call (priv->proxy, "GetSignalQuality", &err, ++ G_TYPE_INVALID, ++ G_TYPE_UINT, &priv->signal_quality, ++ G_TYPE_INVALID)) { ++ g_warning ("Error in getting signal quality: %s", err->message); ++ g_error_free (err); ++ } ++ } ++ ++ return priv->signal_quality; ++} ++ ++guint32 ++nma_gsm_modem_get_registration_info (NMAGsmModem *modem, ++ char **operator_code, ++ char **operator_name) ++{ ++ NMAGsmModemPrivate *priv = NMA_GSM_MODEM_GET_PRIVATE (modem); ++ GError *err = NULL; ++ guint32 status = MM_GSM_MODEM_REG_STATUS_UNKNOWN; ++ ++ g_return_val_if_fail (NMA_IS_GSM_MODEM (modem), 0); ++ ++ if (!dbus_g_proxy_call (priv->proxy, "GetRegistrationInfo", &err, ++ G_TYPE_INVALID, ++ G_TYPE_UINT, &status, ++ G_TYPE_STRING, operator_code, ++ G_TYPE_STRING, operator_name, ++ G_TYPE_INVALID)) { ++ g_warning ("Error in getting network mode: %s", err->message); ++ g_error_free (err); ++ } ++ ++ return status; ++} ++ ++guint32 ++nma_gsm_modem_get_network_mode (NMAGsmModem *modem) ++{ ++ NMAGsmModemPrivate *priv = NMA_GSM_MODEM_GET_PRIVATE (modem); ++ GError *err = NULL; ++ guint32 network_mode = 0; ++ ++ g_return_val_if_fail (NMA_IS_GSM_MODEM (modem), 0); ++ ++ if (!dbus_g_proxy_call (priv->proxy, "GetNetworkMode", &err, ++ G_TYPE_INVALID, ++ G_TYPE_UINT, &network_mode, ++ G_TYPE_INVALID)) { ++ g_warning ("Error in getting network mode: %s", err->message); ++ g_error_free (err); ++ } ++ ++ return network_mode; ++} ++ ++static void ++nma_gsm_modem_init (NMAGsmModem *modem) ++{ ++ NMAGsmModemPrivate *priv = NMA_GSM_MODEM_GET_PRIVATE (modem); ++ ++ priv->signal_quality = -1; ++} ++ ++static void ++dispose (GObject *object) ++{ ++ NMAGsmModemPrivate *priv = NMA_GSM_MODEM_GET_PRIVATE (object); ++ ++ if (priv->disposed) ++ return; ++ ++ priv->disposed = TRUE; ++ ++ if (priv->proxy) ++ g_object_unref (priv->proxy); ++ ++ G_OBJECT_CLASS (nma_gsm_modem_parent_class)->dispose (object); ++} ++ ++static void ++nma_gsm_modem_class_init (NMAGsmModemClass *modem_class) ++{ ++ GObjectClass *object_class = G_OBJECT_CLASS (modem_class); ++ ++ g_type_class_add_private (modem_class, sizeof (NMAGsmModemPrivate)); ++ ++ /* virtual methods */ ++ object_class->dispose = dispose; ++ ++ /* Signals */ ++ signals[SIGNAL_QUALITY] = ++ g_signal_new ("signal-quality", ++ G_OBJECT_CLASS_TYPE (object_class), ++ G_SIGNAL_RUN_FIRST, ++ G_STRUCT_OFFSET (NMAGsmModemClass, signal_quality), ++ NULL, NULL, ++ g_cclosure_marshal_VOID__UINT, ++ G_TYPE_NONE, 1, ++ G_TYPE_UINT); ++ ++ signals[NETWORK_MODE] = ++ g_signal_new ("network-mode", ++ G_OBJECT_CLASS_TYPE (object_class), ++ G_SIGNAL_RUN_FIRST, ++ G_STRUCT_OFFSET (NMAGsmModemClass, network_mode), ++ NULL, NULL, ++ g_cclosure_marshal_VOID__UINT, ++ G_TYPE_NONE, 1, ++ G_TYPE_UINT); ++} +diff --git a/src/nma-gsm-modem.h b/src/nma-gsm-modem.h +new file mode 100644 +index 0000000..90e7ae0 +--- /dev/null ++++ b/src/nma-gsm-modem.h +@@ -0,0 +1,45 @@ ++/* -*- Mode: C; tab-width: 5; indent-tabs-mode: t; c-basic-offset: 5 -*- */ ++ ++#ifndef NMA_GSM_MODEM_H ++#define NMA_GSM_MODEM_H ++ ++#include <glib/gtypes.h> ++#include <glib-object.h> ++#include <dbus/dbus-glib.h> ++ ++G_BEGIN_DECLS ++ ++#define NMA_TYPE_GSM_MODEM (nma_gsm_modem_get_type ()) ++#define NMA_GSM_MODEM(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NMA_TYPE_GSM_MODEM, NMAGsmModem)) ++#define NMA_GSM_MODEM_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NMA_TYPE_GSM_MODEM, NMAGsmModemClass)) ++#define NMA_IS_GSM_MODEM(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NMA_TYPE_GSM_MODEM)) ++#define NMA_IS_GSM_MODEM_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), NMA_TYPE_GSM_MODEM)) ++#define NMA_GSM_MODEM_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NMA_TYPE_GSM_MODEM, NMAGsmModemClass)) ++ ++typedef struct { ++ GObject parent; ++} NMAGsmModem; ++ ++typedef struct { ++ GObjectClass parent; ++ ++ /* Signals */ ++ void (*signal_quality) (NMAGsmModem *modem, guint32 signal_quality); ++ void (*network_mode) (NMAGsmModem *modem, guint32 network_mode); ++} NMAGsmModemClass; ++ ++GType nma_gsm_modem_get_type (void); ++ ++NMAGsmModem *nma_gsm_modem_new (DBusGConnection *bus, ++ const char *object_path); ++ ++guint32 nma_gsm_modem_get_signal_quality (NMAGsmModem *modem); ++guint32 nma_gsm_modem_get_registration_info (NMAGsmModem *modem, ++ char **operator_code, ++ char **operator_name); ++ ++guint32 nma_gsm_modem_get_network_mode (NMAGsmModem *modem); ++ ++G_END_DECLS ++ ++#endif /* NMA_GSM_MODEM_H */ |