
Currently "src/" mostly contains the source code of the daemon. I say mostly, because that is not true, there are also the device, settings, wwan, ppp plugins, the initrd generator, the pppd and dhcp helper, and probably more. Also we have source code under libnm-core/, libnm/, clients/, and shared/ directories. That is all confusing. We should have one "src" directory, that contains subdirectories. Those subdirectories should contain individual parts (libraries or applications), that possibly have dependencies on other subdirectories. There should be a flat hierarchy of directories under src/, which contains individual modules. As the name "src/" is already taken, that prevents any sensible restructuring of the code. As a first step, move "src/" to "src/core/". This gives space to reorganize the code better by moving individual components into "src/". For inspiration, look at systemd's "src/" directory. https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/merge_requests/743
552 lines
19 KiB
C
552 lines
19 KiB
C
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
|
/*
|
|
* Dan Williams <dcbw@redhat.com>
|
|
* Sjoerd Simons <sjoerd.simons@collabora.co.uk>
|
|
* Daniel Drake <dsd@laptop.org>
|
|
* Copyright (C) 2005 - 2014 Red Hat, Inc.
|
|
* Copyright (C) 2008 Collabora Ltd.
|
|
* Copyright (C) 2009 One Laptop per Child
|
|
*/
|
|
|
|
#include "nm-default.h"
|
|
|
|
#include "nm-device-olpc-mesh.h"
|
|
|
|
#include <netinet/in.h>
|
|
#include <sys/stat.h>
|
|
#include <sys/wait.h>
|
|
#include <signal.h>
|
|
#include <unistd.h>
|
|
#include <sys/ioctl.h>
|
|
|
|
#include "devices/nm-device.h"
|
|
#include "nm-device-wifi.h"
|
|
#include "devices/nm-device-private.h"
|
|
#include "nm-utils.h"
|
|
#include "NetworkManagerUtils.h"
|
|
#include "nm-act-request.h"
|
|
#include "nm-setting-connection.h"
|
|
#include "nm-setting-olpc-mesh.h"
|
|
#include "nm-manager.h"
|
|
#include "platform/nm-platform.h"
|
|
|
|
#define _NMLOG_DEVICE_TYPE NMDeviceOlpcMesh
|
|
#include "devices/nm-device-logging.h"
|
|
|
|
/*****************************************************************************/
|
|
|
|
NM_GOBJECT_PROPERTIES_DEFINE(NMDeviceOlpcMesh, PROP_COMPANION, PROP_ACTIVE_CHANNEL, );
|
|
|
|
typedef struct {
|
|
NMDevice * companion;
|
|
NMManager *manager;
|
|
bool stage1_waiting : 1;
|
|
} NMDeviceOlpcMeshPrivate;
|
|
|
|
struct _NMDeviceOlpcMesh {
|
|
NMDevice parent;
|
|
NMDeviceOlpcMeshPrivate _priv;
|
|
};
|
|
|
|
struct _NMDeviceOlpcMeshClass {
|
|
NMDeviceClass parent;
|
|
};
|
|
|
|
G_DEFINE_TYPE(NMDeviceOlpcMesh, nm_device_olpc_mesh, NM_TYPE_DEVICE)
|
|
|
|
#define NM_DEVICE_OLPC_MESH_GET_PRIVATE(self) \
|
|
_NM_GET_PRIVATE(self, NMDeviceOlpcMesh, NM_IS_DEVICE_OLPC_MESH, NMDevice)
|
|
|
|
/*****************************************************************************/
|
|
|
|
static gboolean
|
|
get_autoconnect_allowed(NMDevice *device)
|
|
{
|
|
NMDeviceOlpcMesh * self = NM_DEVICE_OLPC_MESH(device);
|
|
NMDeviceOlpcMeshPrivate *priv = NM_DEVICE_OLPC_MESH_GET_PRIVATE(self);
|
|
|
|
/* We can't even connect if we don't have a companion yet. */
|
|
if (!priv->companion)
|
|
return FALSE;
|
|
|
|
/* We must not attempt to autoconnect when the companion is connected or
|
|
* connecting, * because we'd tear down its connection. */
|
|
if (nm_device_get_state(priv->companion) > NM_DEVICE_STATE_DISCONNECTED)
|
|
return FALSE;
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
#define DEFAULT_SSID "olpc-mesh"
|
|
|
|
static gboolean
|
|
complete_connection(NMDevice * device,
|
|
NMConnection * connection,
|
|
const char * specific_object,
|
|
NMConnection *const *existing_connections,
|
|
GError ** error)
|
|
{
|
|
NMSettingOlpcMesh *s_mesh;
|
|
|
|
s_mesh = nm_connection_get_setting_olpc_mesh(connection);
|
|
if (!s_mesh) {
|
|
s_mesh = (NMSettingOlpcMesh *) nm_setting_olpc_mesh_new();
|
|
nm_connection_add_setting(connection, NM_SETTING(s_mesh));
|
|
}
|
|
|
|
if (!nm_setting_olpc_mesh_get_ssid(s_mesh)) {
|
|
gs_unref_bytes GBytes *ssid = NULL;
|
|
|
|
ssid = g_bytes_new_static(DEFAULT_SSID, NM_STRLEN(DEFAULT_SSID));
|
|
g_object_set(G_OBJECT(s_mesh), NM_SETTING_OLPC_MESH_SSID, ssid, NULL);
|
|
}
|
|
|
|
if (!nm_setting_olpc_mesh_get_dhcp_anycast_address(s_mesh)) {
|
|
const char *anycast = "c0:27:c0:27:c0:27";
|
|
|
|
g_object_set(G_OBJECT(s_mesh), NM_SETTING_OLPC_MESH_DHCP_ANYCAST_ADDRESS, anycast, NULL);
|
|
}
|
|
|
|
nm_utils_complete_generic(nm_device_get_platform(device),
|
|
connection,
|
|
NM_SETTING_OLPC_MESH_SETTING_NAME,
|
|
existing_connections,
|
|
NULL,
|
|
_("Mesh"),
|
|
NULL,
|
|
NULL,
|
|
FALSE); /* No IPv6 by default */
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
|
|
static NMActStageReturn
|
|
act_stage1_prepare(NMDevice *device, NMDeviceStateReason *out_failure_reason)
|
|
{
|
|
NMDeviceOlpcMesh * self = NM_DEVICE_OLPC_MESH(device);
|
|
NMDeviceOlpcMeshPrivate *priv = NM_DEVICE_OLPC_MESH_GET_PRIVATE(self);
|
|
|
|
/* disconnect companion device, if it is connected */
|
|
if (nm_device_get_act_request(NM_DEVICE(priv->companion))) {
|
|
_LOGI(LOGD_OLPC, "disconnecting companion device %s", nm_device_get_iface(priv->companion));
|
|
/* FIXME: VPN stuff here is a bug; but we can't really change API now... */
|
|
nm_device_state_changed(NM_DEVICE(priv->companion),
|
|
NM_DEVICE_STATE_DISCONNECTED,
|
|
NM_DEVICE_STATE_REASON_USER_REQUESTED);
|
|
_LOGI(LOGD_OLPC, "companion %s disconnected", nm_device_get_iface(priv->companion));
|
|
}
|
|
|
|
/* wait with continuing configuration until the companion device is done scanning */
|
|
if (nm_device_wifi_get_scanning(NM_DEVICE_WIFI(priv->companion))) {
|
|
priv->stage1_waiting = TRUE;
|
|
return NM_ACT_STAGE_RETURN_POSTPONE;
|
|
}
|
|
|
|
priv->stage1_waiting = FALSE;
|
|
return NM_ACT_STAGE_RETURN_SUCCESS;
|
|
}
|
|
|
|
static gboolean
|
|
_mesh_set_channel(NMDeviceOlpcMesh *self, guint32 channel)
|
|
{
|
|
NMPlatform *platform;
|
|
int ifindex = nm_device_get_ifindex(NM_DEVICE(self));
|
|
guint32 old_channel;
|
|
|
|
platform = nm_device_get_platform(NM_DEVICE(self));
|
|
old_channel = nm_platform_mesh_get_channel(platform, ifindex);
|
|
|
|
if (channel == 0)
|
|
channel = old_channel;
|
|
|
|
/* We want to call this even if the channel number is the same,
|
|
* because that actually starts the mesh with the configured mesh ID. */
|
|
if (!nm_platform_mesh_set_channel(platform, ifindex, channel))
|
|
return FALSE;
|
|
|
|
if (old_channel != channel)
|
|
_notify(self, PROP_ACTIVE_CHANNEL);
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
static NMActStageReturn
|
|
act_stage2_config(NMDevice *device, NMDeviceStateReason *out_failure_reason)
|
|
{
|
|
NMDeviceOlpcMesh * self = NM_DEVICE_OLPC_MESH(device);
|
|
NMSettingOlpcMesh *s_mesh;
|
|
GBytes * ssid;
|
|
const char * anycast_addr;
|
|
gboolean success;
|
|
|
|
s_mesh = nm_device_get_applied_setting(device, NM_TYPE_SETTING_OLPC_MESH);
|
|
g_return_val_if_fail(s_mesh, NM_ACT_STAGE_RETURN_FAILURE);
|
|
|
|
ssid = nm_setting_olpc_mesh_get_ssid(s_mesh);
|
|
|
|
nm_device_take_down(NM_DEVICE(self), TRUE);
|
|
success = nm_platform_mesh_set_ssid(nm_device_get_platform(device),
|
|
nm_device_get_ifindex(device),
|
|
g_bytes_get_data(ssid, NULL),
|
|
g_bytes_get_size(ssid));
|
|
nm_device_bring_up(NM_DEVICE(self), TRUE, NULL);
|
|
if (!success) {
|
|
_LOGW(LOGD_WIFI, "Unable to set the mesh ID");
|
|
return NM_ACT_STAGE_RETURN_FAILURE;
|
|
}
|
|
|
|
anycast_addr = nm_setting_olpc_mesh_get_dhcp_anycast_address(s_mesh);
|
|
nm_device_set_dhcp_anycast_address(device, anycast_addr);
|
|
|
|
if (!_mesh_set_channel(self, nm_setting_olpc_mesh_get_channel(s_mesh))) {
|
|
_LOGW(LOGD_WIFI, "Unable to set the mesh channel");
|
|
return NM_ACT_STAGE_RETURN_FAILURE;
|
|
}
|
|
|
|
return NM_ACT_STAGE_RETURN_SUCCESS;
|
|
}
|
|
|
|
static gboolean
|
|
is_available(NMDevice *device, NMDeviceCheckDevAvailableFlags flags)
|
|
{
|
|
NMDeviceOlpcMesh *self = NM_DEVICE_OLPC_MESH(device);
|
|
|
|
if (!NM_DEVICE_OLPC_MESH_GET_PRIVATE(self)->companion) {
|
|
_LOGD(LOGD_WIFI, "not available because companion not found");
|
|
return FALSE;
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
|
|
static void
|
|
companion_cleanup(NMDeviceOlpcMesh *self)
|
|
{
|
|
NMDeviceOlpcMeshPrivate *priv = NM_DEVICE_OLPC_MESH_GET_PRIVATE(self);
|
|
|
|
if (priv->companion) {
|
|
nm_device_wifi_scanning_prohibited_track(NM_DEVICE_WIFI(priv->companion), self, FALSE);
|
|
g_signal_handlers_disconnect_by_data(priv->companion, self);
|
|
g_clear_object(&priv->companion);
|
|
}
|
|
_notify(self, PROP_COMPANION);
|
|
}
|
|
|
|
static void
|
|
companion_notify_cb(NMDeviceWifi *companion, GParamSpec *pspec, gpointer user_data)
|
|
{
|
|
NMDeviceOlpcMesh * self = NM_DEVICE_OLPC_MESH(user_data);
|
|
NMDeviceOlpcMeshPrivate *priv = NM_DEVICE_OLPC_MESH_GET_PRIVATE(self);
|
|
|
|
nm_assert(NM_IS_DEVICE_WIFI(companion));
|
|
nm_assert(priv->companion == (gpointer) companion);
|
|
|
|
if (!priv->stage1_waiting)
|
|
return;
|
|
|
|
if (!nm_device_wifi_get_scanning(NM_DEVICE_WIFI(companion))) {
|
|
priv->stage1_waiting = FALSE;
|
|
nm_device_activate_schedule_stage1_device_prepare(NM_DEVICE(self), FALSE);
|
|
}
|
|
}
|
|
|
|
/* disconnect from mesh if someone starts using the companion */
|
|
static void
|
|
companion_state_changed_cb(NMDeviceWifi * companion,
|
|
NMDeviceState state,
|
|
NMDeviceState old_state,
|
|
NMDeviceStateReason reason,
|
|
gpointer user_data)
|
|
{
|
|
NMDeviceOlpcMesh *self = NM_DEVICE_OLPC_MESH(user_data);
|
|
NMDeviceState self_state = nm_device_get_state(NM_DEVICE(self));
|
|
|
|
if (old_state > NM_DEVICE_STATE_DISCONNECTED && state <= NM_DEVICE_STATE_DISCONNECTED) {
|
|
nm_device_emit_recheck_auto_activate(NM_DEVICE(self));
|
|
}
|
|
|
|
if (self_state < NM_DEVICE_STATE_PREPARE || self_state > NM_DEVICE_STATE_ACTIVATED
|
|
|| state < NM_DEVICE_STATE_PREPARE || state > NM_DEVICE_STATE_ACTIVATED)
|
|
return;
|
|
|
|
_LOGD(LOGD_OLPC, "disconnecting mesh due to companion connectivity");
|
|
/* FIXME: VPN stuff here is a bug; but we can't really change API now... */
|
|
nm_device_state_changed(NM_DEVICE(self),
|
|
NM_DEVICE_STATE_DISCONNECTED,
|
|
NM_DEVICE_STATE_REASON_USER_REQUESTED);
|
|
}
|
|
|
|
static gboolean
|
|
companion_autoconnect_allowed_cb(NMDeviceWifi *companion, gpointer user_data)
|
|
{
|
|
NMDeviceOlpcMesh *self = NM_DEVICE_OLPC_MESH(user_data);
|
|
NMDeviceState state = nm_device_get_state(NM_DEVICE(self));
|
|
|
|
/* Don't allow the companion to autoconnect while a mesh connection is
|
|
* active */
|
|
return (state < NM_DEVICE_STATE_PREPARE) || (state > NM_DEVICE_STATE_ACTIVATED);
|
|
}
|
|
|
|
static gboolean
|
|
check_companion(NMDeviceOlpcMesh *self, NMDevice *other)
|
|
{
|
|
NMDeviceOlpcMeshPrivate *priv = NM_DEVICE_OLPC_MESH_GET_PRIVATE(self);
|
|
const char * my_addr, *their_addr;
|
|
|
|
if (!NM_IS_DEVICE_WIFI(other))
|
|
return FALSE;
|
|
|
|
my_addr = nm_device_get_hw_address(NM_DEVICE(self));
|
|
their_addr = nm_device_get_hw_address(other);
|
|
if (!nm_utils_hwaddr_matches(my_addr, -1, their_addr, -1))
|
|
return FALSE;
|
|
|
|
nm_assert(priv->companion == NULL);
|
|
priv->companion = g_object_ref(other);
|
|
|
|
_LOGI(LOGD_OLPC, "found companion Wi-Fi device %s", nm_device_get_iface(other));
|
|
|
|
g_signal_connect(G_OBJECT(other),
|
|
NM_DEVICE_STATE_CHANGED,
|
|
G_CALLBACK(companion_state_changed_cb),
|
|
self);
|
|
|
|
g_signal_connect(G_OBJECT(other),
|
|
"notify::" NM_DEVICE_WIFI_SCANNING,
|
|
G_CALLBACK(companion_notify_cb),
|
|
self);
|
|
|
|
g_signal_connect(G_OBJECT(other),
|
|
NM_DEVICE_AUTOCONNECT_ALLOWED,
|
|
G_CALLBACK(companion_autoconnect_allowed_cb),
|
|
self);
|
|
|
|
_notify(self, PROP_COMPANION);
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
static void
|
|
device_added_cb(NMManager *manager, NMDevice *other, gpointer user_data)
|
|
{
|
|
NMDeviceOlpcMesh * self = NM_DEVICE_OLPC_MESH(user_data);
|
|
NMDeviceOlpcMeshPrivate *priv = NM_DEVICE_OLPC_MESH_GET_PRIVATE(self);
|
|
|
|
if (!priv->companion && check_companion(self, other)) {
|
|
nm_device_queue_recheck_available(NM_DEVICE(self),
|
|
NM_DEVICE_STATE_REASON_NONE,
|
|
NM_DEVICE_STATE_REASON_NONE);
|
|
nm_device_remove_pending_action(NM_DEVICE(self),
|
|
NM_PENDING_ACTION_WAITING_FOR_COMPANION,
|
|
FALSE);
|
|
}
|
|
}
|
|
|
|
static void
|
|
device_removed_cb(NMManager *manager, NMDevice *other, gpointer user_data)
|
|
{
|
|
NMDeviceOlpcMesh *self = NM_DEVICE_OLPC_MESH(user_data);
|
|
|
|
if (other == NM_DEVICE_OLPC_MESH_GET_PRIVATE(self)->companion)
|
|
companion_cleanup(self);
|
|
}
|
|
|
|
static void
|
|
find_companion(NMDeviceOlpcMesh *self)
|
|
{
|
|
NMDeviceOlpcMeshPrivate *priv = NM_DEVICE_OLPC_MESH_GET_PRIVATE(self);
|
|
const CList * tmp_lst;
|
|
NMDevice * candidate;
|
|
|
|
if (priv->companion)
|
|
return;
|
|
|
|
nm_device_add_pending_action(NM_DEVICE(self), NM_PENDING_ACTION_WAITING_FOR_COMPANION, TRUE);
|
|
|
|
/* Try to find the companion if it's already known to the NMManager */
|
|
nm_manager_for_each_device (priv->manager, candidate, tmp_lst) {
|
|
if (check_companion(self, candidate)) {
|
|
nm_device_queue_recheck_available(NM_DEVICE(self),
|
|
NM_DEVICE_STATE_REASON_NONE,
|
|
NM_DEVICE_STATE_REASON_NONE);
|
|
nm_device_remove_pending_action(NM_DEVICE(self),
|
|
NM_PENDING_ACTION_WAITING_FOR_COMPANION,
|
|
TRUE);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
static void
|
|
state_changed(NMDevice * device,
|
|
NMDeviceState new_state,
|
|
NMDeviceState old_state,
|
|
NMDeviceStateReason reason)
|
|
{
|
|
NMDeviceOlpcMesh * self = NM_DEVICE_OLPC_MESH(device);
|
|
NMDeviceOlpcMeshPrivate *priv = NM_DEVICE_OLPC_MESH_GET_PRIVATE(self);
|
|
|
|
if (new_state == NM_DEVICE_STATE_UNAVAILABLE)
|
|
find_companion(self);
|
|
|
|
if (priv->companion) {
|
|
gboolean temporarily_prohibited = FALSE;
|
|
|
|
if (new_state >= NM_DEVICE_STATE_PREPARE && new_state <= NM_DEVICE_STATE_IP_CONFIG) {
|
|
/* Don't allow the companion to scan while configuring the mesh interface */
|
|
temporarily_prohibited = TRUE;
|
|
}
|
|
nm_device_wifi_scanning_prohibited_track(NM_DEVICE_WIFI(priv->companion),
|
|
self,
|
|
temporarily_prohibited);
|
|
}
|
|
}
|
|
|
|
static guint32
|
|
get_dhcp_timeout_for_device(NMDevice *device, int addr_family)
|
|
{
|
|
/* shorter timeout for mesh connectivity */
|
|
return 20;
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
|
|
static void
|
|
get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec)
|
|
{
|
|
NMDeviceOlpcMesh * self = NM_DEVICE_OLPC_MESH(object);
|
|
NMDevice * device = NM_DEVICE(self);
|
|
NMDeviceOlpcMeshPrivate *priv = NM_DEVICE_OLPC_MESH_GET_PRIVATE(self);
|
|
|
|
switch (prop_id) {
|
|
case PROP_COMPANION:
|
|
nm_dbus_utils_g_value_set_object_path(value, priv->companion);
|
|
break;
|
|
case PROP_ACTIVE_CHANNEL:
|
|
g_value_set_uint(value,
|
|
nm_platform_mesh_get_channel(nm_device_get_platform(device),
|
|
nm_device_get_ifindex(device)));
|
|
break;
|
|
default:
|
|
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
|
|
break;
|
|
}
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
|
|
static void
|
|
nm_device_olpc_mesh_init(NMDeviceOlpcMesh *self)
|
|
{}
|
|
|
|
static void
|
|
constructed(GObject *object)
|
|
{
|
|
NMDeviceOlpcMesh * self = NM_DEVICE_OLPC_MESH(object);
|
|
NMDeviceOlpcMeshPrivate *priv = NM_DEVICE_OLPC_MESH_GET_PRIVATE(self);
|
|
|
|
G_OBJECT_CLASS(nm_device_olpc_mesh_parent_class)->constructed(object);
|
|
|
|
priv->manager = g_object_ref(NM_MANAGER_GET);
|
|
|
|
g_signal_connect(priv->manager, NM_MANAGER_DEVICE_ADDED, G_CALLBACK(device_added_cb), self);
|
|
g_signal_connect(priv->manager, NM_MANAGER_DEVICE_REMOVED, G_CALLBACK(device_removed_cb), self);
|
|
}
|
|
|
|
NMDevice *
|
|
nm_device_olpc_mesh_new(const char *iface)
|
|
{
|
|
return g_object_new(NM_TYPE_DEVICE_OLPC_MESH,
|
|
NM_DEVICE_IFACE,
|
|
iface,
|
|
NM_DEVICE_TYPE_DESC,
|
|
"802.11 OLPC Mesh",
|
|
NM_DEVICE_DEVICE_TYPE,
|
|
NM_DEVICE_TYPE_OLPC_MESH,
|
|
NM_DEVICE_LINK_TYPE,
|
|
NM_LINK_TYPE_OLPC_MESH,
|
|
NULL);
|
|
}
|
|
|
|
static void
|
|
dispose(GObject *object)
|
|
{
|
|
NMDeviceOlpcMesh * self = NM_DEVICE_OLPC_MESH(object);
|
|
NMDeviceOlpcMeshPrivate *priv = NM_DEVICE_OLPC_MESH_GET_PRIVATE(self);
|
|
|
|
companion_cleanup(self);
|
|
|
|
if (priv->manager) {
|
|
g_signal_handlers_disconnect_by_func(priv->manager, G_CALLBACK(device_added_cb), self);
|
|
g_signal_handlers_disconnect_by_func(priv->manager, G_CALLBACK(device_removed_cb), self);
|
|
g_clear_object(&priv->manager);
|
|
}
|
|
|
|
G_OBJECT_CLASS(nm_device_olpc_mesh_parent_class)->dispose(object);
|
|
}
|
|
|
|
static const NMDBusInterfaceInfoExtended interface_info_device_olpc_mesh = {
|
|
.parent = NM_DEFINE_GDBUS_INTERFACE_INFO_INIT(
|
|
NM_DBUS_INTERFACE_DEVICE_OLPC_MESH,
|
|
.signals = NM_DEFINE_GDBUS_SIGNAL_INFOS(&nm_signal_info_property_changed_legacy, ),
|
|
.properties = NM_DEFINE_GDBUS_PROPERTY_INFOS(
|
|
NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("HwAddress",
|
|
"s",
|
|
NM_DEVICE_HW_ADDRESS),
|
|
NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("Companion",
|
|
"o",
|
|
NM_DEVICE_OLPC_MESH_COMPANION),
|
|
NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L(
|
|
"ActiveChannel",
|
|
"u",
|
|
NM_DEVICE_OLPC_MESH_ACTIVE_CHANNEL), ), ),
|
|
.legacy_property_changed = TRUE,
|
|
};
|
|
|
|
static void
|
|
nm_device_olpc_mesh_class_init(NMDeviceOlpcMeshClass *klass)
|
|
{
|
|
GObjectClass * object_class = G_OBJECT_CLASS(klass);
|
|
NMDBusObjectClass *dbus_object_class = NM_DBUS_OBJECT_CLASS(klass);
|
|
NMDeviceClass * device_class = NM_DEVICE_CLASS(klass);
|
|
|
|
object_class->constructed = constructed;
|
|
object_class->get_property = get_property;
|
|
object_class->dispose = dispose;
|
|
|
|
dbus_object_class->interface_infos = NM_DBUS_INTERFACE_INFOS(&interface_info_device_olpc_mesh);
|
|
|
|
device_class->connection_type_supported = NM_SETTING_OLPC_MESH_SETTING_NAME;
|
|
device_class->connection_type_check_compatible = NM_SETTING_OLPC_MESH_SETTING_NAME;
|
|
device_class->link_types = NM_DEVICE_DEFINE_LINK_TYPES(NM_LINK_TYPE_OLPC_MESH);
|
|
|
|
device_class->get_autoconnect_allowed = get_autoconnect_allowed;
|
|
device_class->complete_connection = complete_connection;
|
|
device_class->is_available = is_available;
|
|
device_class->act_stage1_prepare = act_stage1_prepare;
|
|
device_class->act_stage2_config = act_stage2_config;
|
|
device_class->state_changed = state_changed;
|
|
device_class->get_dhcp_timeout_for_device = get_dhcp_timeout_for_device;
|
|
|
|
obj_properties[PROP_COMPANION] = g_param_spec_string(NM_DEVICE_OLPC_MESH_COMPANION,
|
|
"",
|
|
"",
|
|
NULL,
|
|
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
|
|
|
|
obj_properties[PROP_ACTIVE_CHANNEL] =
|
|
g_param_spec_uint(NM_DEVICE_OLPC_MESH_ACTIVE_CHANNEL,
|
|
"",
|
|
"",
|
|
0,
|
|
G_MAXUINT32,
|
|
0,
|
|
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
|
|
|
|
g_object_class_install_properties(object_class, _PROPERTY_ENUMS_LAST, obj_properties);
|
|
}
|