// SPDX-License-Identifier: GPL-2.0+
/* NetworkManager Applet -- allow user control over networking
*
* Dan Williams <dcbw@redhat.com>
*
* Copyright 2008 - 2014 Red Hat, Inc.
* Copyright 2008 Novell, Inc.
*/
#include "nm-default.h"
#include "applet.h"
#include "applet-device-bt.h"
#include "applet-dialogs.h"
static gboolean
bt_new_auto_connection (NMDevice *device,
gpointer dclass_data,
AppletNewAutoConnectionCallback callback,
gpointer callback_data)
{
// FIXME: call gnome-bluetooth setup wizard
return FALSE;
}
static void
bt_add_menu_item (NMDevice *device,
gboolean multiple__devices,
const GPtrArray *connections,
NMConnection *active,
GtkWidget *menu,
NMApplet *applet)
{
const char *text;
GtkWidget *item;
text = nm_device_bt_get_name (NM_DEVICE_BT (device));
if (!text)
text = nm_device_get_description (device);
item = applet_menu_item_create_device_item_helper (device, applet, text);
gtk_widget_set_sensitive (item, FALSE);
gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
gtk_widget_show (item);
if (connections->len)
applet_add_connection_items (device, connections, TRUE, active, NMA_ADD_ACTIVE, menu, applet);
/* Notify user of unmanaged or unavailable device */
item = nma_menu_device_get_menu_item (device, applet, NULL);
if (item) {
gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
gtk_widget_show (item);
}
if (!nma_menu_device_check_unusable (device)) {
/* Add menu items for existing bluetooth connections for this device */
if (connections->len) {
applet_menu_item_add_complex_separator_helper (menu, applet, _("Available"));
applet_add_connection_items (device, connections, TRUE, active, NMA_ADD_INACTIVE, menu, applet);
}
}
}
static void
bt_notify_connected (NMDevice *device,
const char *msg,
NMApplet *applet)
{
applet_do_notify_with_pref (applet,
_("Connection Established"),
msg ? msg : _("You are now connected to the mobile broadband network."),
"nm-device-wwan",
PREF_DISABLE_CONNECTED_NOTIFICATIONS);
}
static void
bt_get_icon (NMDevice *device,
NMDeviceState state,
NMConnection *connection,
GdkPixbuf **out_pixbuf,
const char **out_icon_name,
char **tip,
NMApplet *applet)
{
NMSettingConnection *s_con;
const char *id;
g_return_if_fail (out_icon_name && !*out_icon_name);
g_return_if_fail (tip && !*tip);
id = nm_device_get_iface (NM_DEVICE (device));
if (connection) {
s_con = nm_connection_get_setting_connection (connection);
id = nm_setting_connection_get_id (s_con);
}
switch (state) {
case NM_DEVICE_STATE_PREPARE:
*tip = g_strdup_printf (_("Preparing mobile broadband connection “%s”…"), id);
break;
case NM_DEVICE_STATE_CONFIG:
*tip = g_strdup_printf (_("Configuring mobile broadband connection “%s”…"), id);
break;
case NM_DEVICE_STATE_NEED_AUTH:
*tip = g_strdup_printf (_("User authentication required for mobile broadband connection “%s”…"), id);
break;
case NM_DEVICE_STATE_IP_CONFIG:
*tip = g_strdup_printf (_("Requesting a network address for “%s”…"), id);
break;
case NM_DEVICE_STATE_ACTIVATED:
*out_icon_name = "nm-device-wwan";
*tip = g_strdup_printf (_("Mobile broadband connection “%s” active"), id);
break;
default:
break;
}
}
typedef struct {
SecretsRequest req;
GtkWidget *dialog;
GtkEntry *secret_entry;
char *secret_name;
} NMBtSecretsInfo;
static void
free_bt_secrets_info (SecretsRequest *req)
{
NMBtSecretsInfo *info = (NMBtSecretsInfo *) req;
if (info->dialog) {
gtk_widget_hide (info->dialog);
gtk_widget_destroy (info->dialog);
}
g_free (info->secret_name);
}
static void
get_bt_secrets_cb (GtkDialog *dialog,
gint response,
gpointer user_data)
{
SecretsRequest *req = user_data;
NMBtSecretsInfo *info = (NMBtSecretsInfo *) req;
NMSetting *setting;
GError *error = NULL;
if (response == GTK_RESPONSE_OK) {
setting = nm_connection_get_setting_by_name (req->connection, req->setting_name);
if (setting) {
/* Normally we'd want to get all the settings's secrets and return those
* to NM too (since NM wants them), but since the only other secrets for 3G
* connections are PINs, and since the phone obviously has to be unlocked
* to even make the Bluetooth connection, we can skip doing that here for
* Bluetooth devices.
*/
/* Update the password */
g_object_set (G_OBJECT (setting),
info->secret_name, gtk_entry_get_text (info->secret_entry),
NULL);
} else {
g_set_error (&error,
NM_SECRET_AGENT_ERROR,
NM_SECRET_AGENT_ERROR_FAILED,
"%s.%d (%s): unhandled setting '%s'",
__FILE__, __LINE__, __func__, req->setting_name);
}
} else {
g_set_error (&error,
NM_SECRET_AGENT_ERROR,
NM_SECRET_AGENT_ERROR_FAILED,
"%s.%d (%s): canceled",
__FILE__, __LINE__, __func__);
}
applet_secrets_request_complete_setting (req, req->setting_name, error);
applet_secrets_request_free (req);
g_clear_error (&error);
}
static gboolean
bt_get_secrets (SecretsRequest *req, GError **error)
{
NMBtSecretsInfo *info = (NMBtSecretsInfo *) req;
GtkWidget *widget;
GtkEntry *secret_entry = NULL;
applet_secrets_request_set_free_func (req, free_bt_secrets_info);
if (!req->hints || !g_strv_length (req->hints)) {
g_set_error (error,
NM_SECRET_AGENT_ERROR,
NM_SECRET_AGENT_ERROR_FAILED,
"%s.%d (%s): missing secrets hints.",
__FILE__, __LINE__, __func__);
return FALSE;
}
info->secret_name = g_strdup (req->hints[0]);
if ( (!strcmp (req->setting_name, NM_SETTING_CDMA_SETTING_NAME) && !strcmp (info->secret_name, NM_SETTING_CDMA_PASSWORD))
|| (!strcmp (req->setting_name, NM_SETTING_GSM_SETTING_NAME) && !strcmp (info->secret_name, NM_SETTING_GSM_PASSWORD)))
widget = applet_mobile_password_dialog_new (req->connection, &secret_entry);
else {
g_set_error (error,
NM_SECRET_AGENT_ERROR,
NM_SECRET_AGENT_ERROR_FAILED,
"%s.%d (%s): unknown secrets hint '%s'.",
__FILE__, __LINE__, __func__, info->secret_name);
return FALSE;
}
info->dialog = widget;
info->secret_entry = secret_entry;
if (!widget || !secret_entry) {
g_set_error (error,
NM_SECRET_AGENT_ERROR,
NM_SECRET_AGENT_ERROR_FAILED,
"%s.%d (%s): error asking for CDMA secrets.",
__FILE__, __LINE__, __func__);
return FALSE;
}
g_signal_connect (widget, "response", G_CALLBACK (get_bt_secrets_cb), info);
gtk_window_set_position (GTK_WINDOW (widget), GTK_WIN_POS_CENTER_ALWAYS);
gtk_widget_realize (GTK_WIDGET (widget));
gtk_window_present (GTK_WINDOW (widget));
return TRUE;
}
NMADeviceClass *
applet_device_bt_get_class (NMApplet *applet)
{
NMADeviceClass *dclass;
dclass = g_slice_new0 (NMADeviceClass);
if (!dclass)
return NULL;
dclass->new_auto_connection = bt_new_auto_connection;
dclass->add_menu_item = bt_add_menu_item;
dclass->notify_connected = bt_notify_connected;
dclass->get_icon = bt_get_icon;
dclass->get_secrets = bt_get_secrets;
dclass->secrets_request_size = sizeof (NMBtSecretsInfo);
return dclass;
}