mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager.git
synced 2026-05-05 22:48:01 +02:00
bluez: create NMConnection for PAN devices
Create a new NMConnection for PAN devices if no compatible connection exists and export it via DBUS. This has the effect of always exposing any usable PAN-capable device. https://bugzilla.gnome.org/show_bug.cgi?id=701078 Signed-off-by: Thomas Haller <thaller@redhat.com>
This commit is contained in:
parent
98daf270ba
commit
57e19288b7
2 changed files with 131 additions and 5 deletions
|
|
@ -36,6 +36,7 @@ libnm-util/nm-setting-wireless.c
|
||||||
libnm-util/nm-utils.c
|
libnm-util/nm-utils.c
|
||||||
policy/org.freedesktop.NetworkManager.policy.in.in
|
policy/org.freedesktop.NetworkManager.policy.in.in
|
||||||
src/main.c
|
src/main.c
|
||||||
|
src/bluez-manager/nm-bluez-device.c
|
||||||
src/dhcp-manager/nm-dhcp-dhclient.c
|
src/dhcp-manager/nm-dhcp-dhclient.c
|
||||||
src/dhcp-manager/nm-dhcp-dhclient-utils.c
|
src/dhcp-manager/nm-dhcp-dhclient-utils.c
|
||||||
src/dhcp-manager/nm-dhcp-manager.c
|
src/dhcp-manager/nm-dhcp-manager.c
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <glib.h>
|
#include <glib.h>
|
||||||
|
#include <glib/gi18n.h>
|
||||||
#include <gio/gio.h>
|
#include <gio/gio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <net/ethernet.h>
|
#include <net/ethernet.h>
|
||||||
|
|
@ -35,6 +36,7 @@
|
||||||
#endif
|
#endif
|
||||||
#include "nm-bluez-device.h"
|
#include "nm-bluez-device.h"
|
||||||
#include "nm-logging.h"
|
#include "nm-logging.h"
|
||||||
|
#include "nm-utils.h"
|
||||||
|
|
||||||
|
|
||||||
G_DEFINE_TYPE (NMBluezDevice, nm_bluez_device, G_TYPE_OBJECT)
|
G_DEFINE_TYPE (NMBluezDevice, nm_bluez_device, G_TYPE_OBJECT)
|
||||||
|
|
@ -67,6 +69,9 @@ typedef struct {
|
||||||
|
|
||||||
NMConnectionProvider *provider;
|
NMConnectionProvider *provider;
|
||||||
GSList *connections;
|
GSList *connections;
|
||||||
|
|
||||||
|
NMConnection *pan_connection;
|
||||||
|
gboolean pan_connection_no_autocreate;
|
||||||
} NMBluezDevicePrivate;
|
} NMBluezDevicePrivate;
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -90,6 +95,11 @@ enum {
|
||||||
};
|
};
|
||||||
static guint signals[LAST_SIGNAL] = { 0 };
|
static guint signals[LAST_SIGNAL] = { 0 };
|
||||||
|
|
||||||
|
|
||||||
|
static void cp_connection_added (NMConnectionProvider *provider,
|
||||||
|
NMConnection *connection, NMBluezDevice *self);
|
||||||
|
|
||||||
|
|
||||||
/***********************************************************/
|
/***********************************************************/
|
||||||
|
|
||||||
const char *
|
const char *
|
||||||
|
|
@ -156,6 +166,102 @@ nm_bluez_device_get_connected (NMBluezDevice *self)
|
||||||
return NM_BLUEZ_DEVICE_GET_PRIVATE (self)->connected;
|
return NM_BLUEZ_DEVICE_GET_PRIVATE (self)->connected;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
pan_connection_check_create (NMBluezDevice *self)
|
||||||
|
{
|
||||||
|
NMConnection *connection;
|
||||||
|
NMConnection *added;
|
||||||
|
NMSetting *setting;
|
||||||
|
char *uuid, *id;
|
||||||
|
GByteArray *bdaddr_array;
|
||||||
|
GError *error = NULL;
|
||||||
|
NMBluezDevicePrivate *priv = NM_BLUEZ_DEVICE_GET_PRIVATE (self);
|
||||||
|
|
||||||
|
g_return_if_fail (priv->capabilities & NM_BT_CAPABILITY_NAP);
|
||||||
|
g_return_if_fail (priv->connections == NULL);
|
||||||
|
g_return_if_fail (priv->name);
|
||||||
|
|
||||||
|
if (priv->pan_connection || priv->pan_connection_no_autocreate) {
|
||||||
|
/* already have a connection or we don't want to create one, nothing to do. */
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!nm_connection_provider_has_connections_loaded (priv->provider)) {
|
||||||
|
/* do not try to create any connections until the connection provider is ready. */
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Only try once to create a connection. If it does not succeed, we do not try again. Also,
|
||||||
|
* if the connection gets deleted later, do not create another one for this device. */
|
||||||
|
priv->pan_connection_no_autocreate = TRUE;
|
||||||
|
|
||||||
|
/* create a new connection */
|
||||||
|
|
||||||
|
connection = nm_connection_new ();
|
||||||
|
|
||||||
|
/* Setting: Connection */
|
||||||
|
uuid = nm_utils_uuid_generate ();
|
||||||
|
id = g_strdup_printf (_("%s Network"), priv->name);
|
||||||
|
setting = nm_setting_connection_new ();
|
||||||
|
g_object_set (setting,
|
||||||
|
NM_SETTING_CONNECTION_ID, id,
|
||||||
|
NM_SETTING_CONNECTION_UUID, uuid,
|
||||||
|
NM_SETTING_CONNECTION_AUTOCONNECT, FALSE,
|
||||||
|
NM_SETTING_CONNECTION_TYPE, NM_SETTING_BLUETOOTH_SETTING_NAME,
|
||||||
|
NULL);
|
||||||
|
nm_connection_add_setting (connection, setting);
|
||||||
|
|
||||||
|
/* Setting: Bluetooth */
|
||||||
|
bdaddr_array = g_byte_array_sized_new (sizeof (priv->bin_address));
|
||||||
|
g_byte_array_append (bdaddr_array, priv->bin_address, sizeof (priv->bin_address));
|
||||||
|
setting = nm_setting_bluetooth_new ();
|
||||||
|
g_object_set (G_OBJECT (setting),
|
||||||
|
NM_SETTING_BLUETOOTH_BDADDR, bdaddr_array,
|
||||||
|
NM_SETTING_BLUETOOTH_TYPE, NM_SETTING_BLUETOOTH_TYPE_PANU,
|
||||||
|
NULL);
|
||||||
|
nm_connection_add_setting (connection, setting);
|
||||||
|
g_byte_array_free (bdaddr_array, TRUE);
|
||||||
|
|
||||||
|
/* Setting: IPv4 */
|
||||||
|
setting = nm_setting_ip4_config_new ();
|
||||||
|
g_object_set (G_OBJECT (setting),
|
||||||
|
NM_SETTING_IP4_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO,
|
||||||
|
NM_SETTING_IP4_CONFIG_MAY_FAIL, FALSE,
|
||||||
|
NULL);
|
||||||
|
nm_connection_add_setting (connection, setting);
|
||||||
|
|
||||||
|
/* Setting: IPv6 */
|
||||||
|
setting = nm_setting_ip6_config_new ();
|
||||||
|
g_object_set (G_OBJECT (setting),
|
||||||
|
NM_SETTING_IP6_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_AUTO,
|
||||||
|
NM_SETTING_IP6_CONFIG_MAY_FAIL, TRUE,
|
||||||
|
NULL);
|
||||||
|
nm_connection_add_setting (connection, setting);
|
||||||
|
|
||||||
|
/* Adding a new connection raises a signal which eventually calls check_emit_usable (again)
|
||||||
|
* which then already finds the suitable connection in priv->connections. This is confusing,
|
||||||
|
* so block the signal. check_emit_usable will succeed after this function call returns. */
|
||||||
|
g_signal_handlers_block_by_func (priv->provider, cp_connection_added, self);
|
||||||
|
added = nm_connection_provider_add_connection (priv->provider, connection, FALSE, &error);
|
||||||
|
g_signal_handlers_unblock_by_func (priv->provider, cp_connection_added, self);
|
||||||
|
|
||||||
|
if (added) {
|
||||||
|
g_assert (g_slist_find (priv->connections, added));
|
||||||
|
|
||||||
|
priv->pan_connection = added;
|
||||||
|
nm_log_dbg (LOGD_SETTINGS, "added new Bluetooth connection for NAP device '%s': '%s' (%s)", priv->path, id, uuid);
|
||||||
|
} else {
|
||||||
|
nm_log_warn (LOGD_SETTINGS, "couldn't add new Bluetooth connection for NAP device '%s': '%s' (%s): %d / %s",
|
||||||
|
priv->path, id, uuid, error ? error->code : -1,
|
||||||
|
(error && error->message) ? error->message : "(unknown)");
|
||||||
|
g_clear_error (&error);
|
||||||
|
}
|
||||||
|
|
||||||
|
g_object_unref (connection);
|
||||||
|
g_free (id);
|
||||||
|
g_free (uuid);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
check_emit_usable (NMBluezDevice *self)
|
check_emit_usable (NMBluezDevice *self)
|
||||||
{
|
{
|
||||||
|
|
@ -163,12 +269,28 @@ check_emit_usable (NMBluezDevice *self)
|
||||||
gboolean new_usable;
|
gboolean new_usable;
|
||||||
|
|
||||||
new_usable = (priv->initialized && priv->capabilities && priv->name &&
|
new_usable = (priv->initialized && priv->capabilities && priv->name &&
|
||||||
priv->address &&
|
|
||||||
#if WITH_BLUEZ5
|
#if WITH_BLUEZ5
|
||||||
priv->adapter && priv->dbus_connection &&
|
priv->adapter && priv->dbus_connection &&
|
||||||
|
(priv->capabilities & NM_BT_CAPABILITY_NAP) && /* BlueZ5 is only usable with NAP devices */
|
||||||
#endif
|
#endif
|
||||||
priv->connections
|
priv->address);
|
||||||
);
|
|
||||||
|
if (!new_usable)
|
||||||
|
goto END;
|
||||||
|
|
||||||
|
if (priv->connections)
|
||||||
|
goto END;
|
||||||
|
|
||||||
|
if (!(priv->capabilities & NM_BT_CAPABILITY_NAP)) {
|
||||||
|
/* non NAP devices are only usable, if they already have a connection. */
|
||||||
|
new_usable = FALSE;
|
||||||
|
goto END;
|
||||||
|
}
|
||||||
|
|
||||||
|
pan_connection_check_create (self);
|
||||||
|
new_usable = !!priv->pan_connection;
|
||||||
|
|
||||||
|
END:
|
||||||
if (new_usable != priv->usable) {
|
if (new_usable != priv->usable) {
|
||||||
priv->usable = new_usable;
|
priv->usable = new_usable;
|
||||||
g_object_notify (G_OBJECT (self), NM_BLUEZ_DEVICE_USABLE);
|
g_object_notify (G_OBJECT (self), NM_BLUEZ_DEVICE_USABLE);
|
||||||
|
|
@ -201,11 +323,11 @@ connection_compatible (NMBluezDevice *self, NMConnection *connection)
|
||||||
bt_type = nm_setting_bluetooth_get_connection_type (s_bt);
|
bt_type = nm_setting_bluetooth_get_connection_type (s_bt);
|
||||||
if ( g_str_equal (bt_type, NM_SETTING_BLUETOOTH_TYPE_DUN)
|
if ( g_str_equal (bt_type, NM_SETTING_BLUETOOTH_TYPE_DUN)
|
||||||
&& !(priv->capabilities & NM_BT_CAPABILITY_DUN))
|
&& !(priv->capabilities & NM_BT_CAPABILITY_DUN))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
if ( g_str_equal (bt_type, NM_SETTING_BLUETOOTH_TYPE_PANU)
|
if ( g_str_equal (bt_type, NM_SETTING_BLUETOOTH_TYPE_PANU)
|
||||||
&& !(priv->capabilities & NM_BT_CAPABILITY_NAP))
|
&& !(priv->capabilities & NM_BT_CAPABILITY_NAP))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
@ -239,6 +361,9 @@ cp_connection_removed (NMConnectionProvider *provider,
|
||||||
|
|
||||||
if (g_slist_find (priv->connections, connection)) {
|
if (g_slist_find (priv->connections, connection)) {
|
||||||
priv->connections = g_slist_remove (priv->connections, connection);
|
priv->connections = g_slist_remove (priv->connections, connection);
|
||||||
|
if (priv->pan_connection == connection) {
|
||||||
|
priv->pan_connection = NULL;
|
||||||
|
}
|
||||||
g_object_unref (connection);
|
g_object_unref (connection);
|
||||||
check_emit_usable (self);
|
check_emit_usable (self);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue