2019-09-10 11:19:01 +02:00
|
|
|
// SPDX-License-Identifier: LGPL-2.1+
|
2014-07-24 08:53:33 -04:00
|
|
|
/*
|
2019-10-01 09:20:35 +02:00
|
|
|
* Copyright (C) 2007 - 2008 Novell, Inc.
|
|
|
|
|
* Copyright (C) 2007 - 2014 Red Hat, Inc.
|
2014-07-24 08:53:33 -04:00
|
|
|
*/
|
|
|
|
|
|
2016-02-12 14:44:52 +01:00
|
|
|
#include "nm-default.h"
|
2016-02-19 14:57:48 +01:00
|
|
|
|
2016-02-12 14:44:52 +01:00
|
|
|
#include "nm-device-wifi.h"
|
|
|
|
|
|
|
|
|
|
#include "nm-setting-connection.h"
|
|
|
|
|
#include "nm-setting-wireless.h"
|
|
|
|
|
#include "nm-setting-wireless-security.h"
|
|
|
|
|
#include "nm-utils.h"
|
2014-10-09 09:12:42 -04:00
|
|
|
#include "nm-access-point.h"
|
2014-07-24 08:53:33 -04:00
|
|
|
#include "nm-object-private.h"
|
2014-08-26 08:31:04 -04:00
|
|
|
#include "nm-core-internal.h"
|
2014-09-10 13:51:53 -04:00
|
|
|
#include "nm-dbus-helpers.h"
|
|
|
|
|
|
2016-11-23 13:14:08 +01:00
|
|
|
#include "introspection/org.freedesktop.NetworkManager.Device.Wireless.h"
|
2014-07-24 08:53:33 -04:00
|
|
|
|
|
|
|
|
G_DEFINE_TYPE (NMDeviceWifi, nm_device_wifi, NM_TYPE_DEVICE)
|
|
|
|
|
|
|
|
|
|
#define NM_DEVICE_WIFI_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_DEVICE_WIFI, NMDeviceWifiPrivate))
|
|
|
|
|
|
|
|
|
|
void _nm_device_wifi_set_wireless_enabled (NMDeviceWifi *device, gboolean enabled);
|
2014-05-15 14:24:56 -04:00
|
|
|
static void state_changed_cb (NMDevice *device, GParamSpec *pspec, gpointer user_data);
|
2014-07-24 08:53:33 -04:00
|
|
|
|
|
|
|
|
typedef struct {
|
|
|
|
|
NMDeviceWifi *device;
|
2014-09-11 16:27:13 -04:00
|
|
|
GSimpleAsyncResult *simple;
|
2014-07-24 08:53:33 -04:00
|
|
|
} RequestScanInfo;
|
|
|
|
|
|
|
|
|
|
typedef struct {
|
2014-09-10 13:51:53 -04:00
|
|
|
NMDBusDeviceWifi *proxy;
|
2014-07-24 08:53:33 -04:00
|
|
|
|
|
|
|
|
char *hw_address;
|
|
|
|
|
char *perm_hw_address;
|
|
|
|
|
NM80211Mode mode;
|
|
|
|
|
guint32 rate;
|
|
|
|
|
NMAccessPoint *active_ap;
|
|
|
|
|
NMDeviceWifiCapabilities wireless_caps;
|
|
|
|
|
GPtrArray *aps;
|
2018-06-15 13:57:30 +02:00
|
|
|
gint64 last_scan;
|
2014-07-24 08:53:33 -04:00
|
|
|
|
|
|
|
|
RequestScanInfo *scan_info;
|
|
|
|
|
} NMDeviceWifiPrivate;
|
|
|
|
|
|
|
|
|
|
enum {
|
|
|
|
|
PROP_0,
|
|
|
|
|
PROP_HW_ADDRESS,
|
|
|
|
|
PROP_PERM_HW_ADDRESS,
|
|
|
|
|
PROP_MODE,
|
|
|
|
|
PROP_BITRATE,
|
|
|
|
|
PROP_ACTIVE_ACCESS_POINT,
|
|
|
|
|
PROP_WIRELESS_CAPABILITIES,
|
|
|
|
|
PROP_ACCESS_POINTS,
|
2018-02-25 14:53:44 +01:00
|
|
|
PROP_LAST_SCAN,
|
2014-07-24 08:53:33 -04:00
|
|
|
|
|
|
|
|
LAST_PROP
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
enum {
|
|
|
|
|
ACCESS_POINT_ADDED,
|
|
|
|
|
ACCESS_POINT_REMOVED,
|
|
|
|
|
|
|
|
|
|
LAST_SIGNAL
|
|
|
|
|
};
|
|
|
|
|
static guint signals[LAST_SIGNAL] = { 0 };
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* nm_device_wifi_get_hw_address:
|
|
|
|
|
* @device: a #NMDeviceWifi
|
|
|
|
|
*
|
|
|
|
|
* Gets the actual hardware (MAC) address of the #NMDeviceWifi
|
|
|
|
|
*
|
|
|
|
|
* Returns: the actual hardware address. This is the internal string used by the
|
|
|
|
|
* device, and must not be modified.
|
|
|
|
|
**/
|
|
|
|
|
const char *
|
|
|
|
|
nm_device_wifi_get_hw_address (NMDeviceWifi *device)
|
|
|
|
|
{
|
|
|
|
|
g_return_val_if_fail (NM_IS_DEVICE_WIFI (device), NULL);
|
|
|
|
|
|
2016-10-12 19:50:32 +02:00
|
|
|
return nm_str_not_empty (NM_DEVICE_WIFI_GET_PRIVATE (device)->hw_address);
|
2014-07-24 08:53:33 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* nm_device_wifi_get_permanent_hw_address:
|
|
|
|
|
* @device: a #NMDeviceWifi
|
|
|
|
|
*
|
|
|
|
|
* Gets the permanent hardware (MAC) address of the #NMDeviceWifi
|
|
|
|
|
*
|
|
|
|
|
* Returns: the permanent hardware address. This is the internal string used by the
|
|
|
|
|
* device, and must not be modified.
|
|
|
|
|
**/
|
|
|
|
|
const char *
|
|
|
|
|
nm_device_wifi_get_permanent_hw_address (NMDeviceWifi *device)
|
|
|
|
|
{
|
|
|
|
|
g_return_val_if_fail (NM_IS_DEVICE_WIFI (device), NULL);
|
|
|
|
|
|
2016-10-12 19:50:32 +02:00
|
|
|
return nm_str_not_empty (NM_DEVICE_WIFI_GET_PRIVATE (device)->perm_hw_address);
|
2014-07-24 08:53:33 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* nm_device_wifi_get_mode:
|
|
|
|
|
* @device: a #NMDeviceWifi
|
|
|
|
|
*
|
|
|
|
|
* Gets the #NMDeviceWifi mode.
|
|
|
|
|
*
|
|
|
|
|
* Returns: the mode
|
|
|
|
|
**/
|
|
|
|
|
NM80211Mode
|
|
|
|
|
nm_device_wifi_get_mode (NMDeviceWifi *device)
|
|
|
|
|
{
|
|
|
|
|
g_return_val_if_fail (NM_IS_DEVICE_WIFI (device), 0);
|
|
|
|
|
|
|
|
|
|
return NM_DEVICE_WIFI_GET_PRIVATE (device)->mode;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* nm_device_wifi_get_bitrate:
|
|
|
|
|
* @device: a #NMDeviceWifi
|
|
|
|
|
*
|
|
|
|
|
* Gets the bit rate of the #NMDeviceWifi in kbit/s.
|
|
|
|
|
*
|
|
|
|
|
* Returns: the bit rate (kbit/s)
|
|
|
|
|
**/
|
|
|
|
|
guint32
|
|
|
|
|
nm_device_wifi_get_bitrate (NMDeviceWifi *device)
|
|
|
|
|
{
|
|
|
|
|
NMDeviceState state;
|
|
|
|
|
|
|
|
|
|
g_return_val_if_fail (NM_IS_DEVICE_WIFI (device), 0);
|
|
|
|
|
|
|
|
|
|
state = nm_device_get_state (NM_DEVICE (device));
|
|
|
|
|
switch (state) {
|
|
|
|
|
case NM_DEVICE_STATE_IP_CONFIG:
|
|
|
|
|
case NM_DEVICE_STATE_IP_CHECK:
|
|
|
|
|
case NM_DEVICE_STATE_SECONDARIES:
|
|
|
|
|
case NM_DEVICE_STATE_ACTIVATED:
|
|
|
|
|
case NM_DEVICE_STATE_DEACTIVATING:
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return NM_DEVICE_WIFI_GET_PRIVATE (device)->rate;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* nm_device_wifi_get_capabilities:
|
|
|
|
|
* @device: a #NMDeviceWifi
|
|
|
|
|
*
|
|
|
|
|
* Gets the Wi-Fi capabilities of the #NMDeviceWifi.
|
|
|
|
|
*
|
|
|
|
|
* Returns: the capabilities
|
|
|
|
|
**/
|
|
|
|
|
NMDeviceWifiCapabilities
|
|
|
|
|
nm_device_wifi_get_capabilities (NMDeviceWifi *device)
|
|
|
|
|
{
|
|
|
|
|
g_return_val_if_fail (NM_IS_DEVICE_WIFI (device), 0);
|
|
|
|
|
|
|
|
|
|
return NM_DEVICE_WIFI_GET_PRIVATE (device)->wireless_caps;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* nm_device_wifi_get_active_access_point:
|
|
|
|
|
* @device: a #NMDeviceWifi
|
|
|
|
|
*
|
|
|
|
|
* Gets the active #NMAccessPoint.
|
|
|
|
|
*
|
|
|
|
|
* Returns: (transfer none): the access point or %NULL if none is active
|
|
|
|
|
**/
|
|
|
|
|
NMAccessPoint *
|
|
|
|
|
nm_device_wifi_get_active_access_point (NMDeviceWifi *device)
|
|
|
|
|
{
|
|
|
|
|
NMDeviceState state;
|
|
|
|
|
|
|
|
|
|
g_return_val_if_fail (NM_IS_DEVICE_WIFI (device), NULL);
|
|
|
|
|
|
|
|
|
|
state = nm_device_get_state (NM_DEVICE (device));
|
|
|
|
|
switch (state) {
|
|
|
|
|
case NM_DEVICE_STATE_PREPARE:
|
|
|
|
|
case NM_DEVICE_STATE_CONFIG:
|
|
|
|
|
case NM_DEVICE_STATE_NEED_AUTH:
|
|
|
|
|
case NM_DEVICE_STATE_IP_CONFIG:
|
|
|
|
|
case NM_DEVICE_STATE_IP_CHECK:
|
|
|
|
|
case NM_DEVICE_STATE_SECONDARIES:
|
|
|
|
|
case NM_DEVICE_STATE_ACTIVATED:
|
|
|
|
|
case NM_DEVICE_STATE_DEACTIVATING:
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
return NULL;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return NM_DEVICE_WIFI_GET_PRIVATE (device)->active_ap;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* nm_device_wifi_get_access_points:
|
|
|
|
|
* @device: a #NMDeviceWifi
|
|
|
|
|
*
|
|
|
|
|
* Gets all the scanned access points of the #NMDeviceWifi.
|
|
|
|
|
*
|
|
|
|
|
* Returns: (element-type NMAccessPoint): a #GPtrArray containing all the
|
|
|
|
|
* scanned #NMAccessPoints.
|
|
|
|
|
* The returned array is owned by the client and should not be modified.
|
|
|
|
|
**/
|
|
|
|
|
const GPtrArray *
|
|
|
|
|
nm_device_wifi_get_access_points (NMDeviceWifi *device)
|
|
|
|
|
{
|
|
|
|
|
g_return_val_if_fail (NM_IS_DEVICE_WIFI (device), NULL);
|
|
|
|
|
|
2014-08-25 10:33:53 -04:00
|
|
|
return NM_DEVICE_WIFI_GET_PRIVATE (device)->aps;
|
2014-07-24 08:53:33 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* nm_device_wifi_get_access_point_by_path:
|
|
|
|
|
* @device: a #NMDeviceWifi
|
|
|
|
|
* @path: the object path of the access point
|
|
|
|
|
*
|
|
|
|
|
* Gets a #NMAccessPoint by path.
|
|
|
|
|
*
|
|
|
|
|
* Returns: (transfer none): the access point or %NULL if none is found.
|
|
|
|
|
**/
|
|
|
|
|
NMAccessPoint *
|
|
|
|
|
nm_device_wifi_get_access_point_by_path (NMDeviceWifi *device,
|
|
|
|
|
const char *path)
|
|
|
|
|
{
|
|
|
|
|
const GPtrArray *aps;
|
|
|
|
|
int i;
|
|
|
|
|
NMAccessPoint *ap = NULL;
|
|
|
|
|
|
|
|
|
|
g_return_val_if_fail (NM_IS_DEVICE_WIFI (device), NULL);
|
|
|
|
|
g_return_val_if_fail (path != NULL, NULL);
|
|
|
|
|
|
|
|
|
|
aps = nm_device_wifi_get_access_points (device);
|
|
|
|
|
if (!aps)
|
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
|
|
for (i = 0; i < aps->len; i++) {
|
|
|
|
|
NMAccessPoint *candidate = g_ptr_array_index (aps, i);
|
|
|
|
|
if (!strcmp (nm_object_get_path (NM_OBJECT (candidate)), path)) {
|
|
|
|
|
ap = candidate;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return ap;
|
|
|
|
|
}
|
|
|
|
|
|
2018-02-25 14:53:44 +01:00
|
|
|
/**
|
|
|
|
|
* nm_device_wifi_get_last_scan:
|
|
|
|
|
* @device: a #NMDeviceWifi
|
|
|
|
|
*
|
2018-06-15 13:57:30 +02:00
|
|
|
* Returns the timestamp (in CLOCK_BOOTTIME milliseconds) for the last finished
|
2018-02-25 14:53:44 +01:00
|
|
|
* network scan. A value of -1 means the device never scanned for access points.
|
|
|
|
|
*
|
2018-06-15 14:15:27 +02:00
|
|
|
* Use nm_utils_get_timestamp_msec() to obtain current time value suitable for
|
|
|
|
|
* comparing to this value.
|
|
|
|
|
*
|
2018-02-25 14:53:44 +01:00
|
|
|
* Returns: the last scan time in seconds
|
|
|
|
|
*
|
|
|
|
|
* Since: 1.12
|
|
|
|
|
**/
|
2018-06-15 13:57:30 +02:00
|
|
|
gint64
|
2018-02-25 14:53:44 +01:00
|
|
|
nm_device_wifi_get_last_scan (NMDeviceWifi *device)
|
|
|
|
|
{
|
2018-06-15 13:57:30 +02:00
|
|
|
g_return_val_if_fail (NM_IS_DEVICE_WIFI (device), -1);
|
2018-02-25 14:53:44 +01:00
|
|
|
|
2018-06-15 13:57:30 +02:00
|
|
|
return NM_DEVICE_WIFI_GET_PRIVATE (device)->last_scan;
|
2018-02-25 14:53:44 +01:00
|
|
|
}
|
|
|
|
|
|
2015-07-14 09:46:55 +02:00
|
|
|
static GVariant *
|
|
|
|
|
prepare_scan_options (GVariant *options)
|
|
|
|
|
{
|
2019-10-06 14:41:07 +02:00
|
|
|
return options
|
|
|
|
|
?: g_variant_new_array (G_VARIANT_TYPE ("{sv}"), NULL, 0);
|
2015-07-14 09:46:55 +02:00
|
|
|
}
|
|
|
|
|
|
2014-09-11 16:27:13 -04:00
|
|
|
/**
|
|
|
|
|
* nm_device_wifi_request_scan:
|
|
|
|
|
* @device: a #NMDeviceWifi
|
|
|
|
|
* @cancellable: a #GCancellable, or %NULL
|
|
|
|
|
* @error: location for a #GError, or %NULL
|
|
|
|
|
*
|
|
|
|
|
* Request NM to scan for access points on @device. Note that the function
|
|
|
|
|
* returns immediately after requesting the scan, and it may take some time
|
|
|
|
|
* after that for the scan to complete.
|
|
|
|
|
*
|
|
|
|
|
* Returns: %TRUE on success, %FALSE on error, in which case @error will be
|
|
|
|
|
* set.
|
libnm: deprecate synchronous/blocking API in libnm
Note that D-Bus is fundamentally asynchronous. Doing blocking calls
on top of D-Bus is odd, especially for libnm's NMClient. That is because
NMClient essentially is a client-side cache of the objects from the D-Bus
interface. This cache should be filled exclusively by (asynchronous) D-Bus
events (PropertiesChanged). So, making a blocking D-Bus call means to wait
for a response and return it, while queuing all messages that are received
in the meantime.
Basically there are three ways how a synchronous API on NMClient could behave:
1) the call just calls g_dbus_connection_call_sync(). This means
that libnm sends a D-Bus request via GDBusConnection, and blockingly
waits for the response. All D-Bus messages that get received in the
meantime are queued in the GMainContext that belongs to NMClient.
That means, none of these D-Bus events are processed until we
iterate the GMainContext after the call returns. The effect is,
that NMClient (and all cached objects in there) are unaffected by
the D-Bus request.
Most of the synchronous API calls in libnm are of this kind.
The problem is that the strict ordering of D-Bus events gets
violated.
For some API this is not an immediate problem. Take for example
nm_device_wifi_request_scan(). The call merely blockingly tells
NetworkManager to start scanning, but since NetworkManager's D-Bus
API does not directly expose any state that tells whether we are
currently scanning, this out of order processing of the D-Bus
request is a small issue.
The problem is more obvious for nm_client_networking_set_enabled().
After calling it, NM_CLIENT_NETWORKING_ENABLED is still unaffected
and unchanged, because the PropertiesChanged signal from D-Bus
is not yet processed.
This means, while you make such a blocking call, NMClient's state
does not change. But usually you perform the synchronous call
to change some state. In this form, the blocking call is not useful,
because NMClient only changes the state after iterating the GMainContext,
and not after the blocking call returns.
2) like 1), but after making the blocking g_dbus_connection_call_sync(),
update the NMClient cache artificially. This is what
nm_manager_check_connectivity() does, to "fix" bgo#784629.
This also has the problem of out-of-order events, but it kinda
solves the problem of not changing the state during the blocking
call. But it does so by hacking the state of the cache. I think
this is really wrong because the state should only be updated from
the ordered stream of D-Bus messages (PropertiesChanged signal and
similar). When libnm decides to modify the state, there may be already
D-Bus messages queued that affect this very state.
3) instead of calling g_dbus_connection_call_sync(), use the
asynchronous g_dbus_connection_call(). If we would use a sepaate
GMainContext for all D-Bus related calls, we could ensure that
while we block for the response, we iterate that internal main context.
This might be nice, because all events are processed in order and
after the blocking call returns, the NMClient state is up to date.
The are problems however: current blocking API does not do this,
so it's a significant change in behavior. Also, it might be
unexpected to the user that during the blocking call the entire
content of NMClient's cache might change and all pointers to the
cache might be invalidated. Also, of course NMClient would invoke
signals for all the changes that happen.
Another problem is that this would be more effort to implement
and it involves a small performance overhead for all D-Bus related
calls (because we have to serialize all events in an internal
GMainContext first and then invoke them on the caller's context).
Also, if the users wants this behavior, they could implement it themself
by running libnm in their own GMainContext. Note that libnm might
have bugs to make that really working, but that should be fixed
instead of adding such synchrnous API behavior.
Read also [1], for why blocking calls are wrong.
[1] https://smcv.pseudorandom.co.uk/2008/11/nonblocking/
So, all possible behaviors for synchronous API have severe behavioural
issues. Mark all this API as deprecated. Also, this serves the purpose of
identifying blocking D-Bus calls in libnm.
Note that "deprecated" here does not really mean that the API is going
to be removed. We don't break API. The user may:
- continue to use this API. It's deprecated, awkward and discouraged,
but if it works, by all means use it.
- use asynchronous API. That's the only sensible way to use D-Bus.
If libnm lacks a certain asynchronous counterpart, it should be
added.
- use GDBusConnection directly. There really isn't anything wrong
with D-Bus or GDBusConnection. This deprecated API is just a wrapper
around g_dbus_connection_call_sync(). You may call it directly
without feeling dirty.
---
The only other remainging API is the synchronous GInitable call for
NMClient. That is an entirely separate beast and not particularly
wrong (from an API point of view).
Note that synchronous API in NMSecretAgentOld, NMVpnPluginOld and
NMVpnServicePlugin as not deprecated here. These types are not part
of the D-Bus cache and while they have similar issues, it's less severe
because they have less state.
2019-09-04 13:58:43 +02:00
|
|
|
*
|
|
|
|
|
* Deprecated: 1.22, use nm_device_wifi_request_scan_async() or GDBusConnection
|
2014-09-11 16:27:13 -04:00
|
|
|
**/
|
|
|
|
|
gboolean
|
|
|
|
|
nm_device_wifi_request_scan (NMDeviceWifi *device,
|
|
|
|
|
GCancellable *cancellable,
|
|
|
|
|
GError **error)
|
|
|
|
|
{
|
2019-10-06 11:26:09 +02:00
|
|
|
return nm_device_wifi_request_scan_options (device, NULL, cancellable, error);
|
2015-07-14 09:46:55 +02:00
|
|
|
}
|
2014-09-11 16:27:13 -04:00
|
|
|
|
2015-07-14 09:46:55 +02:00
|
|
|
/**
|
|
|
|
|
* nm_device_wifi_request_scan_options:
|
|
|
|
|
* @device: a #NMDeviceWifi
|
|
|
|
|
* @options: dictionary with options for RequestScan(), or %NULL
|
|
|
|
|
* @cancellable: a #GCancellable, or %NULL
|
|
|
|
|
* @error: location for a #GError, or %NULL
|
|
|
|
|
*
|
|
|
|
|
* Request NM to scan for access points on @device. Note that the function
|
|
|
|
|
* returns immediately after requesting the scan, and it may take some time
|
|
|
|
|
* after that for the scan to complete.
|
|
|
|
|
* This is the same as @nm_device_wifi_request_scan except it accepts @options
|
|
|
|
|
* for the scanning. The argument is the dictionary passed to RequestScan()
|
2018-09-15 07:20:54 -04:00
|
|
|
* D-Bus call. Valid options inside the dictionary are:
|
2015-07-14 09:46:55 +02:00
|
|
|
* 'ssids' => array of SSIDs (saay)
|
|
|
|
|
*
|
|
|
|
|
* Returns: %TRUE on success, %FALSE on error, in which case @error will be
|
|
|
|
|
* set.
|
|
|
|
|
*
|
Revert "all: change "Since: 1.2" to "Since: 1.0.4"/"Since: 1.0.6" for backported API"
API should be added with "Since:" of the next release on the same branch.
That means, new API on 1.1 branch (development), should be "Since: 1.2"
and new API on 1.0 branch (stable) will be "Since: 1.0.x". Similarly, new
API on master is NM_AVAILABLE_IN_1_2 and will be added with the linker
version libnl_1_2 -- never the versions of minor releases.
It is also strongly advised that for the 1.0 branch, we only add API
that was previously formerly added on master. IOW, that we only do true
backports of API that already exists on master.
API that gets backported, must also be added to master via NM_BACKPORT_SYMBOL().
That gives ABI compatibility and an application that was build against 1.0.x
will work with 1.y.z version (y > 0) without need for recompiling -- provided
that 1.y.z also contains that API.
There is one important caveat: if a major branch (e.g. current master) has a
linker section of backported APIs (e.g. libnm_1_0_6), we must do the minor release
(1.0.6) before the next major release (1.2). The reason is that after the major
release, the linker section (libnm_1_0_6) must not be extended and thus
the minor release (1.0.6) must be already released at that point.
In general, users should avoid using backported API because it limits
the ability to upgrade to arbitrary later versions. But together with the
previous point (that we only backport API to minor releases), a user that
uses backported API can be sure that a 1.y.z version is ABI compatible with
1.0.x, if the 1.y.z release date was after the release date of 1.0.x.
This reverts commit 02a136682c749a0fd27853c0152d36c44635151f.
2015-08-22 00:57:30 +02:00
|
|
|
* Since: 1.2
|
libnm: deprecate synchronous/blocking API in libnm
Note that D-Bus is fundamentally asynchronous. Doing blocking calls
on top of D-Bus is odd, especially for libnm's NMClient. That is because
NMClient essentially is a client-side cache of the objects from the D-Bus
interface. This cache should be filled exclusively by (asynchronous) D-Bus
events (PropertiesChanged). So, making a blocking D-Bus call means to wait
for a response and return it, while queuing all messages that are received
in the meantime.
Basically there are three ways how a synchronous API on NMClient could behave:
1) the call just calls g_dbus_connection_call_sync(). This means
that libnm sends a D-Bus request via GDBusConnection, and blockingly
waits for the response. All D-Bus messages that get received in the
meantime are queued in the GMainContext that belongs to NMClient.
That means, none of these D-Bus events are processed until we
iterate the GMainContext after the call returns. The effect is,
that NMClient (and all cached objects in there) are unaffected by
the D-Bus request.
Most of the synchronous API calls in libnm are of this kind.
The problem is that the strict ordering of D-Bus events gets
violated.
For some API this is not an immediate problem. Take for example
nm_device_wifi_request_scan(). The call merely blockingly tells
NetworkManager to start scanning, but since NetworkManager's D-Bus
API does not directly expose any state that tells whether we are
currently scanning, this out of order processing of the D-Bus
request is a small issue.
The problem is more obvious for nm_client_networking_set_enabled().
After calling it, NM_CLIENT_NETWORKING_ENABLED is still unaffected
and unchanged, because the PropertiesChanged signal from D-Bus
is not yet processed.
This means, while you make such a blocking call, NMClient's state
does not change. But usually you perform the synchronous call
to change some state. In this form, the blocking call is not useful,
because NMClient only changes the state after iterating the GMainContext,
and not after the blocking call returns.
2) like 1), but after making the blocking g_dbus_connection_call_sync(),
update the NMClient cache artificially. This is what
nm_manager_check_connectivity() does, to "fix" bgo#784629.
This also has the problem of out-of-order events, but it kinda
solves the problem of not changing the state during the blocking
call. But it does so by hacking the state of the cache. I think
this is really wrong because the state should only be updated from
the ordered stream of D-Bus messages (PropertiesChanged signal and
similar). When libnm decides to modify the state, there may be already
D-Bus messages queued that affect this very state.
3) instead of calling g_dbus_connection_call_sync(), use the
asynchronous g_dbus_connection_call(). If we would use a sepaate
GMainContext for all D-Bus related calls, we could ensure that
while we block for the response, we iterate that internal main context.
This might be nice, because all events are processed in order and
after the blocking call returns, the NMClient state is up to date.
The are problems however: current blocking API does not do this,
so it's a significant change in behavior. Also, it might be
unexpected to the user that during the blocking call the entire
content of NMClient's cache might change and all pointers to the
cache might be invalidated. Also, of course NMClient would invoke
signals for all the changes that happen.
Another problem is that this would be more effort to implement
and it involves a small performance overhead for all D-Bus related
calls (because we have to serialize all events in an internal
GMainContext first and then invoke them on the caller's context).
Also, if the users wants this behavior, they could implement it themself
by running libnm in their own GMainContext. Note that libnm might
have bugs to make that really working, but that should be fixed
instead of adding such synchrnous API behavior.
Read also [1], for why blocking calls are wrong.
[1] https://smcv.pseudorandom.co.uk/2008/11/nonblocking/
So, all possible behaviors for synchronous API have severe behavioural
issues. Mark all this API as deprecated. Also, this serves the purpose of
identifying blocking D-Bus calls in libnm.
Note that "deprecated" here does not really mean that the API is going
to be removed. We don't break API. The user may:
- continue to use this API. It's deprecated, awkward and discouraged,
but if it works, by all means use it.
- use asynchronous API. That's the only sensible way to use D-Bus.
If libnm lacks a certain asynchronous counterpart, it should be
added.
- use GDBusConnection directly. There really isn't anything wrong
with D-Bus or GDBusConnection. This deprecated API is just a wrapper
around g_dbus_connection_call_sync(). You may call it directly
without feeling dirty.
---
The only other remainging API is the synchronous GInitable call for
NMClient. That is an entirely separate beast and not particularly
wrong (from an API point of view).
Note that synchronous API in NMSecretAgentOld, NMVpnPluginOld and
NMVpnServicePlugin as not deprecated here. These types are not part
of the D-Bus cache and while they have similar issues, it's less severe
because they have less state.
2019-09-04 13:58:43 +02:00
|
|
|
*
|
|
|
|
|
* Deprecated: 1.22, use nm_device_wifi_request_scan_options_async() or GDBusConnection
|
2015-07-14 09:46:55 +02:00
|
|
|
**/
|
|
|
|
|
gboolean
|
|
|
|
|
nm_device_wifi_request_scan_options (NMDeviceWifi *device,
|
|
|
|
|
GVariant *options,
|
|
|
|
|
GCancellable *cancellable,
|
|
|
|
|
GError **error)
|
|
|
|
|
{
|
2019-10-06 11:26:09 +02:00
|
|
|
g_return_val_if_fail (NM_IS_DEVICE_WIFI (device), FALSE);
|
|
|
|
|
g_return_val_if_fail (!options || g_variant_is_of_type (options, G_VARIANT_TYPE_VARDICT), FALSE);
|
|
|
|
|
g_return_val_if_fail (!cancellable || G_IS_CANCELLABLE (cancellable), FALSE);
|
|
|
|
|
g_return_val_if_fail (!error || !*error, FALSE);
|
|
|
|
|
|
|
|
|
|
if (!options)
|
|
|
|
|
options = g_variant_new_array (G_VARIANT_TYPE ("{sv}"), NULL, 0);
|
|
|
|
|
|
|
|
|
|
return _nm_object_dbus_call_sync_void (device,
|
|
|
|
|
cancellable,
|
|
|
|
|
g_dbus_proxy_get_object_path (G_DBUS_PROXY (NM_DEVICE_WIFI_GET_PRIVATE (device)->proxy)),
|
|
|
|
|
NM_DBUS_INTERFACE_DEVICE_WIRELESS,
|
|
|
|
|
"RequestScan",
|
|
|
|
|
g_variant_new ("(@a{sv})", options),
|
|
|
|
|
G_DBUS_CALL_FLAGS_NONE,
|
|
|
|
|
NM_DBUS_DEFAULT_TIMEOUT_MSEC,
|
|
|
|
|
TRUE,
|
|
|
|
|
error);
|
2014-09-11 16:27:13 -04:00
|
|
|
}
|
|
|
|
|
|
2015-08-14 14:24:16 +02:00
|
|
|
NM_BACKPORT_SYMBOL (libnm_1_0_6, gboolean, nm_device_wifi_request_scan_options,
|
|
|
|
|
(NMDeviceWifi *device, GVariant *options, GCancellable *cancellable, GError **error),
|
|
|
|
|
(device, options, cancellable, error));
|
|
|
|
|
|
2014-07-24 08:53:33 -04:00
|
|
|
static void
|
2014-09-10 13:51:53 -04:00
|
|
|
request_scan_cb (GObject *source,
|
|
|
|
|
GAsyncResult *result,
|
2014-07-24 08:53:33 -04:00
|
|
|
gpointer user_data)
|
|
|
|
|
{
|
|
|
|
|
RequestScanInfo *info = user_data;
|
2014-09-11 16:27:13 -04:00
|
|
|
NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (info->device);
|
|
|
|
|
GError *error = NULL;
|
2014-07-24 08:53:33 -04:00
|
|
|
|
2014-09-11 16:27:13 -04:00
|
|
|
priv->scan_info = NULL;
|
2014-07-24 08:53:33 -04:00
|
|
|
|
2014-09-11 16:27:13 -04:00
|
|
|
if (nmdbus_device_wifi_call_request_scan_finish (NMDBUS_DEVICE_WIFI (source),
|
|
|
|
|
result, &error))
|
|
|
|
|
g_simple_async_result_set_op_res_gboolean (info->simple, TRUE);
|
2014-10-15 18:26:32 -04:00
|
|
|
else {
|
|
|
|
|
g_dbus_error_strip_remote_error (error);
|
2014-09-11 16:27:13 -04:00
|
|
|
g_simple_async_result_take_error (info->simple, error);
|
2014-10-15 18:26:32 -04:00
|
|
|
}
|
2014-07-24 08:53:33 -04:00
|
|
|
|
2014-09-11 16:27:13 -04:00
|
|
|
g_simple_async_result_complete (info->simple);
|
|
|
|
|
g_object_unref (info->simple);
|
2014-09-10 13:51:53 -04:00
|
|
|
g_slice_free (RequestScanInfo, info);
|
2014-07-24 08:53:33 -04:00
|
|
|
}
|
|
|
|
|
|
2015-07-14 09:46:55 +02:00
|
|
|
static void
|
|
|
|
|
_device_wifi_request_scan_async (NMDeviceWifi *device,
|
|
|
|
|
GVariant *options,
|
2014-09-11 16:27:13 -04:00
|
|
|
GCancellable *cancellable,
|
|
|
|
|
GAsyncReadyCallback callback,
|
|
|
|
|
gpointer user_data)
|
2014-07-24 08:53:33 -04:00
|
|
|
{
|
|
|
|
|
NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (device);
|
2014-09-11 16:27:13 -04:00
|
|
|
RequestScanInfo *info;
|
|
|
|
|
GSimpleAsyncResult *simple;
|
2014-07-24 08:53:33 -04:00
|
|
|
|
|
|
|
|
g_return_if_fail (NM_IS_DEVICE_WIFI (device));
|
|
|
|
|
|
2014-09-11 16:27:13 -04:00
|
|
|
simple = g_simple_async_result_new (G_OBJECT (device), callback, user_data,
|
|
|
|
|
nm_device_wifi_request_scan_async);
|
2018-03-05 16:02:24 +01:00
|
|
|
if (cancellable)
|
|
|
|
|
g_simple_async_result_set_check_cancellable (simple, cancellable);
|
2014-09-11 16:27:13 -04:00
|
|
|
|
2014-07-24 08:53:33 -04:00
|
|
|
/* If a scan is in progress, just return */
|
2014-09-11 16:27:13 -04:00
|
|
|
if (priv->scan_info) {
|
|
|
|
|
g_simple_async_result_set_op_res_gboolean (simple, TRUE);
|
|
|
|
|
g_simple_async_result_complete_in_idle (simple);
|
|
|
|
|
g_object_unref (simple);
|
2014-07-24 08:53:33 -04:00
|
|
|
return;
|
2014-09-11 16:27:13 -04:00
|
|
|
}
|
2014-07-24 08:53:33 -04:00
|
|
|
|
|
|
|
|
info = g_slice_new0 (RequestScanInfo);
|
|
|
|
|
info->device = device;
|
2014-09-11 16:27:13 -04:00
|
|
|
info->simple = simple;
|
2014-07-24 08:53:33 -04:00
|
|
|
|
|
|
|
|
priv->scan_info = info;
|
2014-09-10 13:51:53 -04:00
|
|
|
nmdbus_device_wifi_call_request_scan (NM_DEVICE_WIFI_GET_PRIVATE (device)->proxy,
|
2019-10-06 14:41:07 +02:00
|
|
|
prepare_scan_options (g_steal_pointer (&options)),
|
2014-09-11 16:27:13 -04:00
|
|
|
cancellable, request_scan_cb, info);
|
|
|
|
|
}
|
|
|
|
|
|
2015-07-14 09:46:55 +02:00
|
|
|
/**
|
|
|
|
|
* nm_device_wifi_request_scan_async:
|
|
|
|
|
* @device: a #NMDeviceWifi
|
|
|
|
|
* @cancellable: a #GCancellable, or %NULL
|
|
|
|
|
* @callback: callback to be called when the scan has been requested
|
|
|
|
|
* @user_data: caller-specific data passed to @callback
|
|
|
|
|
*
|
|
|
|
|
* Request NM to scan for access points on @device. Note that @callback will be
|
|
|
|
|
* called immediately after requesting the scan, and it may take some time after
|
|
|
|
|
* that for the scan to complete.
|
|
|
|
|
**/
|
|
|
|
|
void
|
|
|
|
|
nm_device_wifi_request_scan_async (NMDeviceWifi *device,
|
|
|
|
|
GCancellable *cancellable,
|
|
|
|
|
GAsyncReadyCallback callback,
|
|
|
|
|
gpointer user_data)
|
|
|
|
|
{
|
|
|
|
|
_device_wifi_request_scan_async (device, NULL, cancellable, callback, user_data);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* nm_device_wifi_request_scan_options_async:
|
|
|
|
|
* @device: a #NMDeviceWifi
|
|
|
|
|
* @options: dictionary with options for RequestScan(), or %NULL
|
|
|
|
|
* @cancellable: a #GCancellable, or %NULL
|
|
|
|
|
* @callback: callback to be called when the scan has been requested
|
|
|
|
|
* @user_data: caller-specific data passed to @callback
|
|
|
|
|
*
|
|
|
|
|
* Request NM to scan for access points on @device. Note that @callback will be
|
|
|
|
|
* called immediately after requesting the scan, and it may take some time after
|
|
|
|
|
* that for the scan to complete.
|
|
|
|
|
* This is the same as @nm_device_wifi_request_scan_async except it accepts @options
|
|
|
|
|
* for the scanning. The argument is the dictionary passed to RequestScan()
|
2018-09-15 07:20:54 -04:00
|
|
|
* D-Bus call. Valid options inside the dictionary are:
|
2015-07-14 09:46:55 +02:00
|
|
|
* 'ssids' => array of SSIDs (saay)
|
|
|
|
|
*
|
Revert "all: change "Since: 1.2" to "Since: 1.0.4"/"Since: 1.0.6" for backported API"
API should be added with "Since:" of the next release on the same branch.
That means, new API on 1.1 branch (development), should be "Since: 1.2"
and new API on 1.0 branch (stable) will be "Since: 1.0.x". Similarly, new
API on master is NM_AVAILABLE_IN_1_2 and will be added with the linker
version libnl_1_2 -- never the versions of minor releases.
It is also strongly advised that for the 1.0 branch, we only add API
that was previously formerly added on master. IOW, that we only do true
backports of API that already exists on master.
API that gets backported, must also be added to master via NM_BACKPORT_SYMBOL().
That gives ABI compatibility and an application that was build against 1.0.x
will work with 1.y.z version (y > 0) without need for recompiling -- provided
that 1.y.z also contains that API.
There is one important caveat: if a major branch (e.g. current master) has a
linker section of backported APIs (e.g. libnm_1_0_6), we must do the minor release
(1.0.6) before the next major release (1.2). The reason is that after the major
release, the linker section (libnm_1_0_6) must not be extended and thus
the minor release (1.0.6) must be already released at that point.
In general, users should avoid using backported API because it limits
the ability to upgrade to arbitrary later versions. But together with the
previous point (that we only backport API to minor releases), a user that
uses backported API can be sure that a 1.y.z version is ABI compatible with
1.0.x, if the 1.y.z release date was after the release date of 1.0.x.
This reverts commit 02a136682c749a0fd27853c0152d36c44635151f.
2015-08-22 00:57:30 +02:00
|
|
|
* Since: 1.2
|
2015-07-14 09:46:55 +02:00
|
|
|
**/
|
|
|
|
|
void
|
|
|
|
|
nm_device_wifi_request_scan_options_async (NMDeviceWifi *device,
|
|
|
|
|
GVariant *options,
|
|
|
|
|
GCancellable *cancellable,
|
|
|
|
|
GAsyncReadyCallback callback,
|
|
|
|
|
gpointer user_data)
|
|
|
|
|
{
|
|
|
|
|
_device_wifi_request_scan_async (device, options, cancellable, callback, user_data);
|
|
|
|
|
}
|
|
|
|
|
|
2015-08-14 14:24:16 +02:00
|
|
|
NM_BACKPORT_SYMBOL (libnm_1_0_6, void, nm_device_wifi_request_scan_options_async,
|
|
|
|
|
(NMDeviceWifi *device, GVariant *options, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data),
|
|
|
|
|
(device, options, cancellable, callback, user_data));
|
|
|
|
|
|
2014-09-11 16:27:13 -04:00
|
|
|
/**
|
|
|
|
|
* nm_device_wifi_request_scan_finish:
|
|
|
|
|
* @device: a #NMDeviceWifi
|
|
|
|
|
* @result: the result passed to the #GAsyncReadyCallback
|
|
|
|
|
* @error: location for a #GError, or %NULL
|
|
|
|
|
*
|
|
|
|
|
* Gets the result of a call to nm_device_wifi_request_scan_async().
|
|
|
|
|
*
|
|
|
|
|
* Returns: %TRUE on success, %FALSE on error, in which case @error will be
|
|
|
|
|
* set.
|
|
|
|
|
**/
|
|
|
|
|
gboolean
|
|
|
|
|
nm_device_wifi_request_scan_finish (NMDeviceWifi *device,
|
|
|
|
|
GAsyncResult *result,
|
|
|
|
|
GError **error)
|
|
|
|
|
{
|
|
|
|
|
GSimpleAsyncResult *simple;
|
|
|
|
|
|
|
|
|
|
g_return_val_if_fail (g_simple_async_result_is_valid (result, G_OBJECT (device), nm_device_wifi_request_scan_async), FALSE);
|
|
|
|
|
|
|
|
|
|
simple = G_SIMPLE_ASYNC_RESULT (result);
|
|
|
|
|
if (g_simple_async_result_propagate_error (simple, error))
|
|
|
|
|
return FALSE;
|
|
|
|
|
else
|
|
|
|
|
return g_simple_async_result_get_op_res_gboolean (simple);
|
2014-07-24 08:53:33 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
2014-08-26 08:31:04 -04:00
|
|
|
clean_up_aps (NMDeviceWifi *self, gboolean in_dispose)
|
2014-07-24 08:53:33 -04:00
|
|
|
{
|
|
|
|
|
NMDeviceWifiPrivate *priv;
|
2014-08-26 08:31:04 -04:00
|
|
|
GPtrArray *aps;
|
|
|
|
|
int i;
|
2014-07-24 08:53:33 -04:00
|
|
|
|
|
|
|
|
g_return_if_fail (NM_IS_DEVICE_WIFI (self));
|
|
|
|
|
|
|
|
|
|
priv = NM_DEVICE_WIFI_GET_PRIVATE (self);
|
|
|
|
|
|
2016-10-12 19:49:46 +02:00
|
|
|
g_clear_object (&priv->active_ap);
|
2014-07-24 08:53:33 -04:00
|
|
|
|
2014-08-26 08:31:04 -04:00
|
|
|
aps = priv->aps;
|
2014-07-24 08:53:33 -04:00
|
|
|
|
2014-08-26 08:31:04 -04:00
|
|
|
if (in_dispose)
|
2014-07-24 08:53:33 -04:00
|
|
|
priv->aps = NULL;
|
2014-08-26 08:31:04 -04:00
|
|
|
else {
|
|
|
|
|
priv->aps = g_ptr_array_new ();
|
|
|
|
|
|
|
|
|
|
for (i = 0; i < aps->len; i++) {
|
|
|
|
|
NMAccessPoint *ap = NM_ACCESS_POINT (g_ptr_array_index (aps, i));
|
|
|
|
|
|
|
|
|
|
g_signal_emit (self, signals[ACCESS_POINT_REMOVED], 0, ap);
|
|
|
|
|
}
|
2014-07-24 08:53:33 -04:00
|
|
|
}
|
2014-08-26 08:31:04 -04:00
|
|
|
|
|
|
|
|
g_ptr_array_unref (aps);
|
2014-07-24 08:53:33 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* _nm_device_wifi_set_wireless_enabled:
|
|
|
|
|
* @device: a #NMDeviceWifi
|
|
|
|
|
* @enabled: %TRUE to enable the device
|
|
|
|
|
*
|
|
|
|
|
* Enables or disables the wireless device.
|
|
|
|
|
**/
|
|
|
|
|
void
|
|
|
|
|
_nm_device_wifi_set_wireless_enabled (NMDeviceWifi *device,
|
|
|
|
|
gboolean enabled)
|
|
|
|
|
{
|
|
|
|
|
g_return_if_fail (NM_IS_DEVICE_WIFI (device));
|
|
|
|
|
|
|
|
|
|
if (!enabled)
|
2014-08-26 08:31:04 -04:00
|
|
|
clean_up_aps (device, FALSE);
|
2014-07-24 08:53:33 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#define WPA_CAPS (NM_WIFI_DEVICE_CAP_CIPHER_TKIP | \
|
|
|
|
|
NM_WIFI_DEVICE_CAP_CIPHER_CCMP | \
|
|
|
|
|
NM_WIFI_DEVICE_CAP_WPA | \
|
|
|
|
|
NM_WIFI_DEVICE_CAP_RSN)
|
|
|
|
|
|
|
|
|
|
#define RSN_CAPS (NM_WIFI_DEVICE_CAP_CIPHER_CCMP | NM_WIFI_DEVICE_CAP_RSN)
|
|
|
|
|
|
|
|
|
|
static gboolean
|
|
|
|
|
has_proto (NMSettingWirelessSecurity *s_wsec, const char *proto)
|
|
|
|
|
{
|
|
|
|
|
int i;
|
|
|
|
|
|
|
|
|
|
for (i = 0; i < nm_setting_wireless_security_get_num_protos (s_wsec); i++) {
|
|
|
|
|
if (g_strcmp0 (proto, nm_setting_wireless_security_get_proto (s_wsec, i)) == 0)
|
|
|
|
|
return TRUE;
|
|
|
|
|
}
|
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static gboolean
|
|
|
|
|
connection_compatible (NMDevice *device, NMConnection *connection, GError **error)
|
|
|
|
|
{
|
|
|
|
|
NMSettingWireless *s_wifi;
|
|
|
|
|
NMSettingWirelessSecurity *s_wsec;
|
2014-07-30 10:57:45 -04:00
|
|
|
const char *hwaddr, *setting_hwaddr;
|
2014-07-24 08:53:33 -04:00
|
|
|
NMDeviceWifiCapabilities wifi_caps;
|
|
|
|
|
const char *key_mgmt;
|
|
|
|
|
|
libnm: merge device-type-specific errors into NMDeviceError
As with the settings, each device type was defining its own error
type, containing either redundant or non-useful error codes. Drop all
of the subtype-specific errors, and reduce things to just
NM_DEVICE_ERROR_FAILED, NM_DEVICE_ERROR_INCOMPATIBLE_CONNECTION, and
NM_DEVICE_ERROR_INVALID_CONNECTION.
The device-type-specific errors were only returned from their
nm_device_connection_compatible() implementations, so this is also a
good opportunity to simplify those, by moving duplicated functionality
into the base NMDevice implementation, and then allowing the
subclasses to assume that the connection has already been validated in
their own code. Most of the implementations now just check that the
connection has the correct type for the device (which can't be done at
the NMDevice level since some device types (eg, Ethernet) support
multiple connection types.)
Also, make sure that all of the error messages are localized.
2014-10-11 14:44:10 -04:00
|
|
|
if (!NM_DEVICE_CLASS (nm_device_wifi_parent_class)->connection_compatible (device, connection, error))
|
2014-07-24 08:53:33 -04:00
|
|
|
return FALSE;
|
|
|
|
|
|
libnm: merge device-type-specific errors into NMDeviceError
As with the settings, each device type was defining its own error
type, containing either redundant or non-useful error codes. Drop all
of the subtype-specific errors, and reduce things to just
NM_DEVICE_ERROR_FAILED, NM_DEVICE_ERROR_INCOMPATIBLE_CONNECTION, and
NM_DEVICE_ERROR_INVALID_CONNECTION.
The device-type-specific errors were only returned from their
nm_device_connection_compatible() implementations, so this is also a
good opportunity to simplify those, by moving duplicated functionality
into the base NMDevice implementation, and then allowing the
subclasses to assume that the connection has already been validated in
their own code. Most of the implementations now just check that the
connection has the correct type for the device (which can't be done at
the NMDevice level since some device types (eg, Ethernet) support
multiple connection types.)
Also, make sure that all of the error messages are localized.
2014-10-11 14:44:10 -04:00
|
|
|
if (!nm_connection_is_type (connection, NM_SETTING_WIRELESS_SETTING_NAME)) {
|
|
|
|
|
g_set_error_literal (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_INCOMPATIBLE_CONNECTION,
|
|
|
|
|
_("The connection was not a Wi-Fi connection."));
|
2014-07-24 08:53:33 -04:00
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Check MAC address */
|
2014-07-30 10:57:45 -04:00
|
|
|
hwaddr = nm_device_wifi_get_permanent_hw_address (NM_DEVICE_WIFI (device));
|
|
|
|
|
if (hwaddr) {
|
|
|
|
|
if (!nm_utils_hwaddr_valid (hwaddr, ETH_ALEN)) {
|
libnm: merge device-type-specific errors into NMDeviceError
As with the settings, each device type was defining its own error
type, containing either redundant or non-useful error codes. Drop all
of the subtype-specific errors, and reduce things to just
NM_DEVICE_ERROR_FAILED, NM_DEVICE_ERROR_INCOMPATIBLE_CONNECTION, and
NM_DEVICE_ERROR_INVALID_CONNECTION.
The device-type-specific errors were only returned from their
nm_device_connection_compatible() implementations, so this is also a
good opportunity to simplify those, by moving duplicated functionality
into the base NMDevice implementation, and then allowing the
subclasses to assume that the connection has already been validated in
their own code. Most of the implementations now just check that the
connection has the correct type for the device (which can't be done at
the NMDevice level since some device types (eg, Ethernet) support
multiple connection types.)
Also, make sure that all of the error messages are localized.
2014-10-11 14:44:10 -04:00
|
|
|
g_set_error_literal (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_FAILED,
|
|
|
|
|
_("Invalid device MAC address."));
|
2014-07-24 08:53:33 -04:00
|
|
|
return FALSE;
|
|
|
|
|
}
|
libnm: merge device-type-specific errors into NMDeviceError
As with the settings, each device type was defining its own error
type, containing either redundant or non-useful error codes. Drop all
of the subtype-specific errors, and reduce things to just
NM_DEVICE_ERROR_FAILED, NM_DEVICE_ERROR_INCOMPATIBLE_CONNECTION, and
NM_DEVICE_ERROR_INVALID_CONNECTION.
The device-type-specific errors were only returned from their
nm_device_connection_compatible() implementations, so this is also a
good opportunity to simplify those, by moving duplicated functionality
into the base NMDevice implementation, and then allowing the
subclasses to assume that the connection has already been validated in
their own code. Most of the implementations now just check that the
connection has the correct type for the device (which can't be done at
the NMDevice level since some device types (eg, Ethernet) support
multiple connection types.)
Also, make sure that all of the error messages are localized.
2014-10-11 14:44:10 -04:00
|
|
|
s_wifi = nm_connection_get_setting_wireless (connection);
|
2014-07-30 10:57:45 -04:00
|
|
|
setting_hwaddr = nm_setting_wireless_get_mac_address (s_wifi);
|
|
|
|
|
if (setting_hwaddr && !nm_utils_hwaddr_matches (setting_hwaddr, -1, hwaddr, -1)) {
|
libnm: merge device-type-specific errors into NMDeviceError
As with the settings, each device type was defining its own error
type, containing either redundant or non-useful error codes. Drop all
of the subtype-specific errors, and reduce things to just
NM_DEVICE_ERROR_FAILED, NM_DEVICE_ERROR_INCOMPATIBLE_CONNECTION, and
NM_DEVICE_ERROR_INVALID_CONNECTION.
The device-type-specific errors were only returned from their
nm_device_connection_compatible() implementations, so this is also a
good opportunity to simplify those, by moving duplicated functionality
into the base NMDevice implementation, and then allowing the
subclasses to assume that the connection has already been validated in
their own code. Most of the implementations now just check that the
connection has the correct type for the device (which can't be done at
the NMDevice level since some device types (eg, Ethernet) support
multiple connection types.)
Also, make sure that all of the error messages are localized.
2014-10-11 14:44:10 -04:00
|
|
|
g_set_error_literal (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_INCOMPATIBLE_CONNECTION,
|
|
|
|
|
_("The MACs of the device and the connection didn't match."));
|
2014-07-24 08:53:33 -04:00
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Check device capabilities; we assume all devices can do WEP at least */
|
|
|
|
|
|
|
|
|
|
s_wsec = nm_connection_get_setting_wireless_security (connection);
|
|
|
|
|
if (s_wsec) {
|
|
|
|
|
/* Connection has security, verify it against the device's capabilities */
|
|
|
|
|
key_mgmt = nm_setting_wireless_security_get_key_mgmt (s_wsec);
|
2019-08-19 15:32:42 +02:00
|
|
|
if ( !g_strcmp0 (key_mgmt, "wpa-psk")
|
2014-07-24 08:53:33 -04:00
|
|
|
|| !g_strcmp0 (key_mgmt, "wpa-eap")) {
|
|
|
|
|
|
libnm: merge device-type-specific errors into NMDeviceError
As with the settings, each device type was defining its own error
type, containing either redundant or non-useful error codes. Drop all
of the subtype-specific errors, and reduce things to just
NM_DEVICE_ERROR_FAILED, NM_DEVICE_ERROR_INCOMPATIBLE_CONNECTION, and
NM_DEVICE_ERROR_INVALID_CONNECTION.
The device-type-specific errors were only returned from their
nm_device_connection_compatible() implementations, so this is also a
good opportunity to simplify those, by moving duplicated functionality
into the base NMDevice implementation, and then allowing the
subclasses to assume that the connection has already been validated in
their own code. Most of the implementations now just check that the
connection has the correct type for the device (which can't be done at
the NMDevice level since some device types (eg, Ethernet) support
multiple connection types.)
Also, make sure that all of the error messages are localized.
2014-10-11 14:44:10 -04:00
|
|
|
wifi_caps = nm_device_wifi_get_capabilities (NM_DEVICE_WIFI (device));
|
|
|
|
|
|
2014-07-24 08:53:33 -04:00
|
|
|
/* Is device only WEP capable? */
|
|
|
|
|
if (!(wifi_caps & WPA_CAPS)) {
|
libnm: merge device-type-specific errors into NMDeviceError
As with the settings, each device type was defining its own error
type, containing either redundant or non-useful error codes. Drop all
of the subtype-specific errors, and reduce things to just
NM_DEVICE_ERROR_FAILED, NM_DEVICE_ERROR_INCOMPATIBLE_CONNECTION, and
NM_DEVICE_ERROR_INVALID_CONNECTION.
The device-type-specific errors were only returned from their
nm_device_connection_compatible() implementations, so this is also a
good opportunity to simplify those, by moving duplicated functionality
into the base NMDevice implementation, and then allowing the
subclasses to assume that the connection has already been validated in
their own code. Most of the implementations now just check that the
connection has the correct type for the device (which can't be done at
the NMDevice level since some device types (eg, Ethernet) support
multiple connection types.)
Also, make sure that all of the error messages are localized.
2014-10-11 14:44:10 -04:00
|
|
|
g_set_error_literal (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_INCOMPATIBLE_CONNECTION,
|
|
|
|
|
_("The device is lacking WPA capabilities required by the connection."));
|
2014-07-24 08:53:33 -04:00
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Make sure WPA2/RSN-only connections don't get chosen for WPA-only cards */
|
|
|
|
|
if (has_proto (s_wsec, "rsn") && !has_proto (s_wsec, "wpa") && !(wifi_caps & RSN_CAPS)) {
|
libnm: merge device-type-specific errors into NMDeviceError
As with the settings, each device type was defining its own error
type, containing either redundant or non-useful error codes. Drop all
of the subtype-specific errors, and reduce things to just
NM_DEVICE_ERROR_FAILED, NM_DEVICE_ERROR_INCOMPATIBLE_CONNECTION, and
NM_DEVICE_ERROR_INVALID_CONNECTION.
The device-type-specific errors were only returned from their
nm_device_connection_compatible() implementations, so this is also a
good opportunity to simplify those, by moving duplicated functionality
into the base NMDevice implementation, and then allowing the
subclasses to assume that the connection has already been validated in
their own code. Most of the implementations now just check that the
connection has the correct type for the device (which can't be done at
the NMDevice level since some device types (eg, Ethernet) support
multiple connection types.)
Also, make sure that all of the error messages are localized.
2014-10-11 14:44:10 -04:00
|
|
|
g_set_error_literal (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_INCOMPATIBLE_CONNECTION,
|
|
|
|
|
_("The device is lacking WPA2/RSN capabilities required by the connection."));
|
2014-07-24 08:53:33 -04:00
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
libnm: merge device-type-specific errors into NMDeviceError
As with the settings, each device type was defining its own error
type, containing either redundant or non-useful error codes. Drop all
of the subtype-specific errors, and reduce things to just
NM_DEVICE_ERROR_FAILED, NM_DEVICE_ERROR_INCOMPATIBLE_CONNECTION, and
NM_DEVICE_ERROR_INVALID_CONNECTION.
The device-type-specific errors were only returned from their
nm_device_connection_compatible() implementations, so this is also a
good opportunity to simplify those, by moving duplicated functionality
into the base NMDevice implementation, and then allowing the
subclasses to assume that the connection has already been validated in
their own code. Most of the implementations now just check that the
connection has the correct type for the device (which can't be done at
the NMDevice level since some device types (eg, Ethernet) support
multiple connection types.)
Also, make sure that all of the error messages are localized.
2014-10-11 14:44:10 -04:00
|
|
|
return TRUE;
|
2014-07-24 08:53:33 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static GType
|
|
|
|
|
get_setting_type (NMDevice *device)
|
|
|
|
|
{
|
|
|
|
|
return NM_TYPE_SETTING_WIRELESS;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static const char *
|
|
|
|
|
get_hw_address (NMDevice *device)
|
|
|
|
|
{
|
|
|
|
|
return nm_device_wifi_get_hw_address (NM_DEVICE_WIFI (device));
|
|
|
|
|
}
|
|
|
|
|
|
2016-10-02 18:22:50 +02:00
|
|
|
/*****************************************************************************/
|
2014-07-24 08:53:33 -04:00
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
nm_device_wifi_init (NMDeviceWifi *device)
|
|
|
|
|
{
|
2014-10-06 21:16:00 -04:00
|
|
|
NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (device);
|
|
|
|
|
|
2014-05-15 14:24:56 -04:00
|
|
|
g_signal_connect (device,
|
|
|
|
|
"notify::" NM_DEVICE_STATE,
|
|
|
|
|
G_CALLBACK (state_changed_cb),
|
|
|
|
|
NULL);
|
2014-10-06 21:16:00 -04:00
|
|
|
|
|
|
|
|
priv->aps = g_ptr_array_new ();
|
2018-02-25 14:53:44 +01:00
|
|
|
priv->last_scan = -1;
|
2014-07-24 08:53:33 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
get_property (GObject *object,
|
|
|
|
|
guint prop_id,
|
|
|
|
|
GValue *value,
|
|
|
|
|
GParamSpec *pspec)
|
|
|
|
|
{
|
|
|
|
|
NMDeviceWifi *self = NM_DEVICE_WIFI (object);
|
|
|
|
|
|
|
|
|
|
switch (prop_id) {
|
|
|
|
|
case PROP_HW_ADDRESS:
|
|
|
|
|
g_value_set_string (value, nm_device_wifi_get_hw_address (self));
|
|
|
|
|
break;
|
|
|
|
|
case PROP_PERM_HW_ADDRESS:
|
|
|
|
|
g_value_set_string (value, nm_device_wifi_get_permanent_hw_address (self));
|
|
|
|
|
break;
|
|
|
|
|
case PROP_MODE:
|
2014-06-26 16:47:46 -04:00
|
|
|
g_value_set_enum (value, nm_device_wifi_get_mode (self));
|
2014-07-24 08:53:33 -04:00
|
|
|
break;
|
|
|
|
|
case PROP_BITRATE:
|
|
|
|
|
g_value_set_uint (value, nm_device_wifi_get_bitrate (self));
|
|
|
|
|
break;
|
|
|
|
|
case PROP_ACTIVE_ACCESS_POINT:
|
|
|
|
|
g_value_set_object (value, nm_device_wifi_get_active_access_point (self));
|
|
|
|
|
break;
|
|
|
|
|
case PROP_WIRELESS_CAPABILITIES:
|
2014-06-26 16:47:46 -04:00
|
|
|
g_value_set_flags (value, nm_device_wifi_get_capabilities (self));
|
2014-07-24 08:53:33 -04:00
|
|
|
break;
|
|
|
|
|
case PROP_ACCESS_POINTS:
|
2014-08-26 08:31:04 -04:00
|
|
|
g_value_take_boxed (value, _nm_utils_copy_object_array (nm_device_wifi_get_access_points (self)));
|
2014-07-24 08:53:33 -04:00
|
|
|
break;
|
2018-02-25 14:53:44 +01:00
|
|
|
case PROP_LAST_SCAN:
|
2018-06-15 13:57:30 +02:00
|
|
|
g_value_set_int64 (value, nm_device_wifi_get_last_scan (self));
|
2018-02-25 14:53:44 +01:00
|
|
|
break;
|
2014-07-24 08:53:33 -04:00
|
|
|
default:
|
|
|
|
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
state_changed_cb (NMDevice *device, GParamSpec *pspec, gpointer user_data)
|
|
|
|
|
{
|
|
|
|
|
NMDeviceWifi *self = NM_DEVICE_WIFI (device);
|
|
|
|
|
NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self);
|
|
|
|
|
|
|
|
|
|
switch (nm_device_get_state (device)) {
|
|
|
|
|
case NM_DEVICE_STATE_UNKNOWN:
|
|
|
|
|
case NM_DEVICE_STATE_UNMANAGED:
|
|
|
|
|
case NM_DEVICE_STATE_UNAVAILABLE:
|
|
|
|
|
case NM_DEVICE_STATE_DISCONNECTED:
|
|
|
|
|
case NM_DEVICE_STATE_FAILED:
|
|
|
|
|
/* Just clear active AP; don't clear the AP list unless wireless is disabled completely */
|
2016-10-12 19:49:46 +02:00
|
|
|
g_clear_object (&priv->active_ap);
|
2014-07-24 08:53:33 -04:00
|
|
|
_nm_object_queue_notify (NM_OBJECT (device), NM_DEVICE_WIFI_ACTIVE_ACCESS_POINT);
|
|
|
|
|
priv->rate = 0;
|
|
|
|
|
_nm_object_queue_notify (NM_OBJECT (device), NM_DEVICE_WIFI_BITRATE);
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
2014-05-15 14:24:56 -04:00
|
|
|
init_dbus (NMObject *object)
|
2014-07-24 08:53:33 -04:00
|
|
|
{
|
2014-05-15 14:24:56 -04:00
|
|
|
NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (object);
|
2014-07-24 08:53:33 -04:00
|
|
|
const NMPropertiesInfo property_info[] = {
|
|
|
|
|
{ NM_DEVICE_WIFI_HW_ADDRESS, &priv->hw_address },
|
|
|
|
|
{ NM_DEVICE_WIFI_PERMANENT_HW_ADDRESS, &priv->perm_hw_address },
|
|
|
|
|
{ NM_DEVICE_WIFI_MODE, &priv->mode },
|
|
|
|
|
{ NM_DEVICE_WIFI_BITRATE, &priv->rate },
|
|
|
|
|
{ NM_DEVICE_WIFI_ACTIVE_ACCESS_POINT, &priv->active_ap, NULL, NM_TYPE_ACCESS_POINT },
|
|
|
|
|
{ NM_DEVICE_WIFI_CAPABILITIES, &priv->wireless_caps },
|
|
|
|
|
{ NM_DEVICE_WIFI_ACCESS_POINTS, &priv->aps, NULL, NM_TYPE_ACCESS_POINT, "access-point" },
|
2018-02-25 14:53:44 +01:00
|
|
|
{ NM_DEVICE_WIFI_LAST_SCAN, &priv->last_scan },
|
2014-07-24 08:53:33 -04:00
|
|
|
{ NULL },
|
|
|
|
|
};
|
|
|
|
|
|
2014-05-15 14:24:56 -04:00
|
|
|
NM_OBJECT_CLASS (nm_device_wifi_parent_class)->init_dbus (object);
|
|
|
|
|
|
2014-09-10 13:51:53 -04:00
|
|
|
priv->proxy = NMDBUS_DEVICE_WIFI (_nm_object_get_proxy (object, NM_DBUS_INTERFACE_DEVICE_WIRELESS));
|
2014-05-15 14:24:56 -04:00
|
|
|
_nm_object_register_properties (object,
|
2014-08-18 14:17:52 -04:00
|
|
|
NM_DBUS_INTERFACE_DEVICE_WIRELESS,
|
2014-07-24 08:53:33 -04:00
|
|
|
property_info);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
access_point_removed (NMDeviceWifi *self, NMAccessPoint *ap)
|
|
|
|
|
{
|
|
|
|
|
NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self);
|
|
|
|
|
|
|
|
|
|
if (ap == priv->active_ap) {
|
2016-10-12 19:49:46 +02:00
|
|
|
g_clear_object (&priv->active_ap);
|
2014-07-24 08:53:33 -04:00
|
|
|
_nm_object_queue_notify (NM_OBJECT (self), NM_DEVICE_WIFI_ACTIVE_ACCESS_POINT);
|
|
|
|
|
|
|
|
|
|
priv->rate = 0;
|
|
|
|
|
_nm_object_queue_notify (NM_OBJECT (self), NM_DEVICE_WIFI_BITRATE);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
dispose (GObject *object)
|
|
|
|
|
{
|
|
|
|
|
NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (object);
|
|
|
|
|
|
2014-08-26 08:31:04 -04:00
|
|
|
if (priv->aps)
|
|
|
|
|
clean_up_aps (NM_DEVICE_WIFI (object), TRUE);
|
2014-07-24 08:53:33 -04:00
|
|
|
|
2016-11-14 18:47:56 +01:00
|
|
|
g_clear_object (&priv->proxy);
|
|
|
|
|
|
2014-07-24 08:53:33 -04:00
|
|
|
G_OBJECT_CLASS (nm_device_wifi_parent_class)->dispose (object);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
finalize (GObject *object)
|
|
|
|
|
{
|
|
|
|
|
NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (object);
|
|
|
|
|
|
|
|
|
|
g_free (priv->hw_address);
|
|
|
|
|
g_free (priv->perm_hw_address);
|
|
|
|
|
|
|
|
|
|
G_OBJECT_CLASS (nm_device_wifi_parent_class)->finalize (object);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
nm_device_wifi_class_init (NMDeviceWifiClass *wifi_class)
|
|
|
|
|
{
|
|
|
|
|
GObjectClass *object_class = G_OBJECT_CLASS (wifi_class);
|
2014-05-15 14:24:56 -04:00
|
|
|
NMObjectClass *nm_object_class = NM_OBJECT_CLASS (wifi_class);
|
2014-07-24 08:53:33 -04:00
|
|
|
NMDeviceClass *device_class = NM_DEVICE_CLASS (wifi_class);
|
|
|
|
|
|
|
|
|
|
g_type_class_add_private (wifi_class, sizeof (NMDeviceWifiPrivate));
|
|
|
|
|
|
|
|
|
|
/* virtual methods */
|
|
|
|
|
object_class->get_property = get_property;
|
|
|
|
|
object_class->dispose = dispose;
|
|
|
|
|
object_class->finalize = finalize;
|
2014-05-15 14:24:56 -04:00
|
|
|
|
|
|
|
|
nm_object_class->init_dbus = init_dbus;
|
|
|
|
|
|
2014-07-24 08:53:33 -04:00
|
|
|
device_class->connection_compatible = connection_compatible;
|
|
|
|
|
device_class->get_setting_type = get_setting_type;
|
|
|
|
|
device_class->get_hw_address = get_hw_address;
|
2014-05-15 14:24:56 -04:00
|
|
|
|
2014-07-24 08:53:33 -04:00
|
|
|
wifi_class->access_point_removed = access_point_removed;
|
|
|
|
|
|
|
|
|
|
/* properties */
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* NMDeviceWifi:hw-address:
|
|
|
|
|
*
|
|
|
|
|
* The hardware (MAC) address of the device.
|
|
|
|
|
**/
|
|
|
|
|
g_object_class_install_property
|
|
|
|
|
(object_class, PROP_HW_ADDRESS,
|
|
|
|
|
g_param_spec_string (NM_DEVICE_WIFI_HW_ADDRESS, "", "",
|
|
|
|
|
NULL,
|
|
|
|
|
G_PARAM_READABLE |
|
|
|
|
|
G_PARAM_STATIC_STRINGS));
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* NMDeviceWifi:perm-hw-address:
|
|
|
|
|
*
|
|
|
|
|
* The hardware (MAC) address of the device.
|
|
|
|
|
**/
|
|
|
|
|
g_object_class_install_property
|
|
|
|
|
(object_class, PROP_PERM_HW_ADDRESS,
|
|
|
|
|
g_param_spec_string (NM_DEVICE_WIFI_PERMANENT_HW_ADDRESS, "", "",
|
|
|
|
|
NULL,
|
|
|
|
|
G_PARAM_READABLE |
|
|
|
|
|
G_PARAM_STATIC_STRINGS));
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* NMDeviceWifi:mode:
|
|
|
|
|
*
|
|
|
|
|
* The mode of the device.
|
|
|
|
|
**/
|
|
|
|
|
g_object_class_install_property
|
|
|
|
|
(object_class, PROP_MODE,
|
2014-06-26 16:47:46 -04:00
|
|
|
g_param_spec_enum (NM_DEVICE_WIFI_MODE, "", "",
|
|
|
|
|
NM_TYPE_802_11_MODE,
|
|
|
|
|
NM_802_11_MODE_UNKNOWN,
|
2014-07-24 08:53:33 -04:00
|
|
|
G_PARAM_READABLE |
|
|
|
|
|
G_PARAM_STATIC_STRINGS));
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* NMDeviceWifi:bitrate:
|
|
|
|
|
*
|
|
|
|
|
* The bit rate of the device in kbit/s.
|
|
|
|
|
**/
|
|
|
|
|
g_object_class_install_property
|
|
|
|
|
(object_class, PROP_BITRATE,
|
|
|
|
|
g_param_spec_uint (NM_DEVICE_WIFI_BITRATE, "", "",
|
|
|
|
|
0, G_MAXUINT32, 0,
|
|
|
|
|
G_PARAM_READABLE |
|
|
|
|
|
G_PARAM_STATIC_STRINGS));
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* NMDeviceWifi:active-access-point:
|
|
|
|
|
*
|
|
|
|
|
* The active #NMAccessPoint of the device.
|
|
|
|
|
**/
|
|
|
|
|
g_object_class_install_property
|
|
|
|
|
(object_class, PROP_ACTIVE_ACCESS_POINT,
|
|
|
|
|
g_param_spec_object (NM_DEVICE_WIFI_ACTIVE_ACCESS_POINT, "", "",
|
|
|
|
|
NM_TYPE_ACCESS_POINT,
|
|
|
|
|
G_PARAM_READABLE |
|
|
|
|
|
G_PARAM_STATIC_STRINGS));
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* NMDeviceWifi:wireless-capabilities:
|
|
|
|
|
*
|
|
|
|
|
* The wireless capabilities of the device.
|
|
|
|
|
**/
|
|
|
|
|
g_object_class_install_property
|
|
|
|
|
(object_class, PROP_WIRELESS_CAPABILITIES,
|
2014-06-26 16:47:46 -04:00
|
|
|
g_param_spec_flags (NM_DEVICE_WIFI_CAPABILITIES, "", "",
|
|
|
|
|
NM_TYPE_DEVICE_WIFI_CAPABILITIES,
|
|
|
|
|
NM_WIFI_DEVICE_CAP_NONE,
|
|
|
|
|
G_PARAM_READABLE |
|
|
|
|
|
G_PARAM_STATIC_STRINGS));
|
2014-07-24 08:53:33 -04:00
|
|
|
|
|
|
|
|
/**
|
2018-03-24 15:18:21 +00:00
|
|
|
* NMDeviceWifi:access-points: (type GPtrArray(NMAccessPoint))
|
2014-07-24 08:53:33 -04:00
|
|
|
*
|
|
|
|
|
* List of all Wi-Fi access points the device can see.
|
|
|
|
|
**/
|
|
|
|
|
g_object_class_install_property
|
|
|
|
|
(object_class, PROP_ACCESS_POINTS,
|
|
|
|
|
g_param_spec_boxed (NM_DEVICE_WIFI_ACCESS_POINTS, "", "",
|
2014-08-26 08:31:04 -04:00
|
|
|
G_TYPE_PTR_ARRAY,
|
2014-07-24 08:53:33 -04:00
|
|
|
G_PARAM_READABLE |
|
|
|
|
|
G_PARAM_STATIC_STRINGS));
|
|
|
|
|
|
2018-02-25 14:53:44 +01:00
|
|
|
/**
|
|
|
|
|
* NMDeviceWifi:last-scan:
|
|
|
|
|
*
|
|
|
|
|
* The timestamp (in CLOCK_BOOTTIME seconds) for the last finished
|
|
|
|
|
* network scan. A value of -1 means the device never scanned for
|
|
|
|
|
* access points.
|
|
|
|
|
*
|
|
|
|
|
* Since: 1.12
|
|
|
|
|
**/
|
|
|
|
|
g_object_class_install_property
|
|
|
|
|
(object_class, PROP_LAST_SCAN,
|
2018-06-15 13:57:30 +02:00
|
|
|
g_param_spec_int64 (NM_DEVICE_WIFI_LAST_SCAN, "", "",
|
|
|
|
|
-1, G_MAXINT64, -1,
|
|
|
|
|
G_PARAM_READABLE |
|
|
|
|
|
G_PARAM_STATIC_STRINGS));
|
2018-02-25 14:53:44 +01:00
|
|
|
|
2014-07-24 08:53:33 -04:00
|
|
|
/* signals */
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* NMDeviceWifi::access-point-added:
|
|
|
|
|
* @device: the Wi-Fi device that received the signal
|
|
|
|
|
* @ap: the new access point
|
|
|
|
|
*
|
|
|
|
|
* Notifies that a #NMAccessPoint is added to the Wi-Fi device.
|
|
|
|
|
**/
|
|
|
|
|
signals[ACCESS_POINT_ADDED] =
|
|
|
|
|
g_signal_new ("access-point-added",
|
|
|
|
|
G_OBJECT_CLASS_TYPE (object_class),
|
|
|
|
|
G_SIGNAL_RUN_FIRST,
|
|
|
|
|
G_STRUCT_OFFSET (NMDeviceWifiClass, access_point_added),
|
|
|
|
|
NULL, NULL,
|
|
|
|
|
g_cclosure_marshal_VOID__OBJECT,
|
|
|
|
|
G_TYPE_NONE, 1,
|
|
|
|
|
G_TYPE_OBJECT);
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* NMDeviceWifi::access-point-removed:
|
|
|
|
|
* @device: the Wi-Fi device that received the signal
|
|
|
|
|
* @ap: the removed access point
|
|
|
|
|
*
|
|
|
|
|
* Notifies that a #NMAccessPoint is removed from the Wi-Fi device.
|
|
|
|
|
**/
|
|
|
|
|
signals[ACCESS_POINT_REMOVED] =
|
|
|
|
|
g_signal_new ("access-point-removed",
|
|
|
|
|
G_OBJECT_CLASS_TYPE (object_class),
|
|
|
|
|
G_SIGNAL_RUN_FIRST,
|
|
|
|
|
G_STRUCT_OFFSET (NMDeviceWifiClass, access_point_removed),
|
|
|
|
|
NULL, NULL,
|
|
|
|
|
g_cclosure_marshal_VOID__OBJECT,
|
|
|
|
|
G_TYPE_NONE, 1,
|
|
|
|
|
G_TYPE_OBJECT);
|
|
|
|
|
}
|