NetworkManager/libnm/nm-wifi-p2p-peer.c
Thomas Haller 05f66697e4 libnm: ignore "Groups" property of WifiP2PPeer
Groups currently are not exposed on D-Bus as separate objects.
Also, we might want to expose the property as "ao" instead of "as".
This API needs more thought.

There are likely no users that rely on this property. So, we will
drop it from server side, until it will be requested and newly designed.

Regardless, NMClient needs to gracefully ignore the property.
Despite we will remove it from 1.24 API, libnm should ignore the
property on previous versions. Mark it accordingly.
2020-01-15 13:53:57 +01:00

567 lines
14 KiB
C

// SPDX-License-Identifier: LGPL-2.1+
/*
* Copyright (C) 2018 - 2019 Red Hat, Inc.
*/
#include "nm-default.h"
#include "nm-wifi-p2p-peer.h"
#include "nm-connection.h"
#include "nm-setting-connection.h"
#include "nm-setting-wifi-p2p.h"
#include "nm-utils.h"
#include "nm-dbus-interface.h"
#include "nm-object-private.h"
/*****************************************************************************/
NM_GOBJECT_PROPERTIES_DEFINE_BASE (
PROP_FLAGS,
PROP_NAME,
PROP_MANUFACTURER,
PROP_MODEL,
PROP_MODEL_NUMBER,
PROP_SERIAL,
PROP_WFD_IES,
PROP_HW_ADDRESS,
PROP_STRENGTH,
PROP_LAST_SEEN,
);
typedef struct {
GBytes *wfd_ies;
char *name;
char *manufacturer;
char *model;
char *model_number;
char *serial;
char *hw_address;
gint32 last_seen;
guint32 flags;
guint8 strength;
} NMWifiP2PPeerPrivate;
struct _NMWifiP2PPeer {
NMObject parent;
NMWifiP2PPeerPrivate _priv;
};
struct _NMWifiP2PPeerClass {
NMObjectClass parent;
};
G_DEFINE_TYPE (NMWifiP2PPeer, nm_wifi_p2p_peer, NM_TYPE_OBJECT)
#define NM_WIFI_P2P_PEER_GET_PRIVATE(self) _NM_GET_PRIVATE (self, NMWifiP2PPeer, NM_IS_WIFI_P2P_PEER, NMObject)
/*****************************************************************************/
/**
* nm_wifi_p2p_peer_get_flags:
* @peer: a #NMWifiP2PPeer
*
* Gets the flags of the P2P peer.
*
* Returns: the flags
*
* Since: 1.16
**/
NM80211ApFlags
nm_wifi_p2p_peer_get_flags (NMWifiP2PPeer *peer)
{
g_return_val_if_fail (NM_IS_WIFI_P2P_PEER (peer), NM_802_11_AP_FLAGS_NONE);
return NM_WIFI_P2P_PEER_GET_PRIVATE (peer)->flags;
}
/**
* nm_wifi_p2p_peer_get_name:
* @peer: a #NMWifiP2PPeer
*
* Gets the name of the P2P peer.
*
* Returns: the name
*
* Since: 1.16
**/
const char *
nm_wifi_p2p_peer_get_name (NMWifiP2PPeer *peer)
{
g_return_val_if_fail (NM_IS_WIFI_P2P_PEER (peer), NULL);
return NM_WIFI_P2P_PEER_GET_PRIVATE (peer)->name;
}
/**
* nm_wifi_p2p_peer_get_manufacturer:
* @peer: a #NMWifiP2PPeer
*
* Gets the manufacturer of the P2P peer.
*
* Returns: the manufacturer
*
* Since: 1.16
**/
const char *
nm_wifi_p2p_peer_get_manufacturer (NMWifiP2PPeer *peer)
{
g_return_val_if_fail (NM_IS_WIFI_P2P_PEER (peer), NULL);
return NM_WIFI_P2P_PEER_GET_PRIVATE (peer)->manufacturer;
}
/**
* nm_wifi_p2p_peer_get_model:
* @peer: a #NMWifiP2PPeer
*
* Gets the model of the P2P peer.
*
* Returns: the model
*
* Since: 1.16
**/
const char *
nm_wifi_p2p_peer_get_model (NMWifiP2PPeer *peer)
{
g_return_val_if_fail (NM_IS_WIFI_P2P_PEER (peer), NULL);
return NM_WIFI_P2P_PEER_GET_PRIVATE (peer)->model;
}
/**
* nm_wifi_p2p_peer_get_model_number:
* @peer: a #NMWifiP2PPeer
*
* Gets the model number of the P2P peer.
*
* Returns: the model number
*
* Since: 1.16
**/
const char *
nm_wifi_p2p_peer_get_model_number (NMWifiP2PPeer *peer)
{
g_return_val_if_fail (NM_IS_WIFI_P2P_PEER (peer), NULL);
return NM_WIFI_P2P_PEER_GET_PRIVATE (peer)->model_number;
}
/**
* nm_wifi_p2p_peer_get_serial:
* @peer: a #NMWifiP2PPeer
*
* Gets the serial number of the P2P peer.
*
* Returns: the serial number
*
* Since: 1.16
**/
const char *
nm_wifi_p2p_peer_get_serial (NMWifiP2PPeer *peer)
{
g_return_val_if_fail (NM_IS_WIFI_P2P_PEER (peer), NULL);
return NM_WIFI_P2P_PEER_GET_PRIVATE (peer)->serial;
}
/**
* nm_wifi_p2p_peer_get_wfd_ies:
* @peer: a #NMWifiP2PPeer
*
* Gets the WFD information elements of the P2P peer.
*
* Returns: (transfer none): the #GBytes containing the WFD IEs, or %NULL.
*
* Since: 1.16
**/
GBytes *
nm_wifi_p2p_peer_get_wfd_ies (NMWifiP2PPeer *peer)
{
NMWifiP2PPeerPrivate *priv;
g_return_val_if_fail (NM_IS_WIFI_P2P_PEER (peer), NULL);
priv = NM_WIFI_P2P_PEER_GET_PRIVATE (peer);
if (!priv->wfd_ies || g_bytes_get_size (priv->wfd_ies) == 0)
return NULL;
return priv->wfd_ies;
}
/**
* nm_wifi_p2p_peer_get_hw_address:
* @peer: a #NMWifiP2PPeer
*
* Gets the hardware address of the P2P peer.
*
* Returns: the hardware address
*
* Since: 1.16
**/
const char *
nm_wifi_p2p_peer_get_hw_address (NMWifiP2PPeer *peer)
{
g_return_val_if_fail (NM_IS_WIFI_P2P_PEER (peer), NULL);
return NM_WIFI_P2P_PEER_GET_PRIVATE (peer)->hw_address;
}
/**
* nm_wifi_p2p_peer_get_strength:
* @peer: a #NMWifiP2PPeer
*
* Gets the current signal strength of the P2P peer as a percentage.
*
* Returns: the signal strength (0 to 100)
*
* Since: 1.16
**/
guint8
nm_wifi_p2p_peer_get_strength (NMWifiP2PPeer *peer)
{
g_return_val_if_fail (NM_IS_WIFI_P2P_PEER (peer), 0);
return NM_WIFI_P2P_PEER_GET_PRIVATE (peer)->strength;
}
/**
* nm_wifi_p2p_peer_get_last_seen:
* @peer: a #NMWifiP2PPeer
*
* Returns the timestamp (in CLOCK_BOOTTIME seconds) for the last time the
* P2P peer was seen. A value of -1 means the P2P peer has never been seen.
*
* Returns: the last seen time in seconds
*
* Since: 1.16
**/
int
nm_wifi_p2p_peer_get_last_seen (NMWifiP2PPeer *peer)
{
g_return_val_if_fail (NM_IS_WIFI_P2P_PEER (peer), -1);
return NM_WIFI_P2P_PEER_GET_PRIVATE (peer)->last_seen;
}
/**
* nm_wifi_p2p_peer_connection_valid:
* @peer: an #NMWifiP2PPeer to validate @connection against
* @connection: an #NMConnection to validate against @peer
*
* Validates a given connection against a given Wi-Fi P2P peer to ensure that
* the connection may be activated with that peer. The connection must match the
* @peer's address and in the future possibly other attributes.
*
* Returns: %TRUE if the connection may be activated with this Wi-Fi P2P Peer,
* %FALSE if it cannot be.
*
* Since: 1.16
**/
gboolean
nm_wifi_p2p_peer_connection_valid (NMWifiP2PPeer *peer, NMConnection *connection)
{
NMSettingConnection *s_con;
NMSettingWifiP2P *s_wifi_p2p;
const char *ctype;
const char *hw_address;
const char *setting_peer;
s_wifi_p2p = (NMSettingWifiP2P *) nm_connection_get_setting (connection, NM_TYPE_SETTING_WIFI_P2P);
if (!s_wifi_p2p)
return FALSE;
s_con = nm_connection_get_setting_connection (connection);
if (!s_con)
return FALSE;
ctype = nm_setting_connection_get_connection_type (s_con);
if ( !ctype
|| !nm_streq (ctype, NM_SETTING_WIFI_P2P_SETTING_NAME))
return FALSE;
/* HW Address check */
hw_address = nm_wifi_p2p_peer_get_hw_address (peer);
if (!hw_address)
return FALSE;
setting_peer = nm_setting_wifi_p2p_get_peer (s_wifi_p2p);
if ( !setting_peer
|| !nm_streq (hw_address, setting_peer))
return FALSE;
return TRUE;
}
/**
* nm_wifi_p2p_peer_filter_connections:
* @peer: an #NMWifiP2PPeer to filter connections for
* @connections: (element-type NMConnection): an array of #NMConnections to
* filter
*
* Filters a given array of connections for a given #NMWifiP2PPeer object and
* returns connections which may be activated with the P2P peer. Any
* returned connections will match the @peers's HW address and in the future
* possibly other attributes.
*
* To obtain the list of connections that are compatible with this P2P peer,
* use nm_client_get_connections() and then filter the returned list for a given
* #NMDevice using nm_device_filter_connections() and finally filter that list
* with this function.
*
* Returns: (transfer container) (element-type NMConnection): an array of
* #NMConnections that could be activated with the given @peer. The array should
* be freed with g_ptr_array_unref() when it is no longer required.
*
* Since: 1.16
**/
GPtrArray *
nm_wifi_p2p_peer_filter_connections (NMWifiP2PPeer *peer, const GPtrArray *connections)
{
GPtrArray *filtered;
guint i;
filtered = g_ptr_array_new_with_free_func (g_object_unref);
for (i = 0; i < connections->len; i++) {
NMConnection *candidate = connections->pdata[i];
if (nm_wifi_p2p_peer_connection_valid (peer, candidate))
g_ptr_array_add (filtered, g_object_ref (candidate));
}
return filtered;
}
/*****************************************************************************/
static void
get_property (GObject *object,
guint prop_id,
GValue *value,
GParamSpec *pspec)
{
NMWifiP2PPeer *peer = NM_WIFI_P2P_PEER (object);
switch (prop_id) {
case PROP_FLAGS:
g_value_set_flags (value, nm_wifi_p2p_peer_get_flags (peer));
break;
case PROP_NAME:
g_value_set_string (value, nm_wifi_p2p_peer_get_name (peer));
break;
case PROP_MANUFACTURER:
g_value_set_string (value, nm_wifi_p2p_peer_get_manufacturer (peer));
break;
case PROP_MODEL:
g_value_set_string (value, nm_wifi_p2p_peer_get_model (peer));
break;
case PROP_MODEL_NUMBER:
g_value_set_string (value, nm_wifi_p2p_peer_get_model_number (peer));
break;
case PROP_SERIAL:
g_value_set_string (value, nm_wifi_p2p_peer_get_serial (peer));
break;
case PROP_WFD_IES:
g_value_set_boxed (value, nm_wifi_p2p_peer_get_wfd_ies (peer));
break;
case PROP_HW_ADDRESS:
g_value_set_string (value, nm_wifi_p2p_peer_get_hw_address (peer));
break;
case PROP_STRENGTH:
g_value_set_uchar (value, nm_wifi_p2p_peer_get_strength (peer));
break;
case PROP_LAST_SEEN:
g_value_set_int (value, nm_wifi_p2p_peer_get_last_seen (peer));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
/*****************************************************************************/
static void
nm_wifi_p2p_peer_init (NMWifiP2PPeer *peer)
{
NM_WIFI_P2P_PEER_GET_PRIVATE (peer)->last_seen = -1;
}
static void
finalize (GObject *object)
{
NMWifiP2PPeerPrivate *priv = NM_WIFI_P2P_PEER_GET_PRIVATE (object);
g_free (priv->name);
g_free (priv->manufacturer);
g_free (priv->model);
g_free (priv->model_number);
g_free (priv->serial);
g_free (priv->hw_address);
g_bytes_unref (priv->wfd_ies);
G_OBJECT_CLASS (nm_wifi_p2p_peer_parent_class)->finalize (object);
}
const NMLDBusMetaIface _nml_dbus_meta_iface_nm_wifip2ppeer = NML_DBUS_META_IFACE_INIT_PROP (
NM_DBUS_INTERFACE_WIFI_P2P_PEER,
nm_wifi_p2p_peer_get_type,
NML_DBUS_META_INTERFACE_PRIO_INSTANTIATE_HIGH,
NML_DBUS_META_IFACE_DBUS_PROPERTIES (
NML_DBUS_META_PROPERTY_INIT_U ("Flags", PROP_FLAGS, NMWifiP2PPeer, _priv.flags ),
NML_DBUS_META_PROPERTY_INIT_IGNORE ("Groups", "as" ),
NML_DBUS_META_PROPERTY_INIT_S ("HwAddress", PROP_HW_ADDRESS, NMWifiP2PPeer, _priv.hw_address ),
NML_DBUS_META_PROPERTY_INIT_I ("LastSeen", PROP_LAST_SEEN, NMWifiP2PPeer, _priv.last_seen ),
NML_DBUS_META_PROPERTY_INIT_S ("Manufacturer", PROP_MANUFACTURER, NMWifiP2PPeer, _priv.manufacturer ),
NML_DBUS_META_PROPERTY_INIT_S ("Model", PROP_MODEL, NMWifiP2PPeer, _priv.model ),
NML_DBUS_META_PROPERTY_INIT_S ("ModelNumber", PROP_MODEL_NUMBER, NMWifiP2PPeer, _priv.model_number ),
NML_DBUS_META_PROPERTY_INIT_S ("Name", PROP_NAME, NMWifiP2PPeer, _priv.name ),
NML_DBUS_META_PROPERTY_INIT_S ("Serial", PROP_SERIAL, NMWifiP2PPeer, _priv.serial ),
NML_DBUS_META_PROPERTY_INIT_Y ("Strength", PROP_STRENGTH, NMWifiP2PPeer, _priv.strength ),
NML_DBUS_META_PROPERTY_INIT_AY ("WfdIEs", PROP_WFD_IES, NMWifiP2PPeer, _priv.wfd_ies ),
),
);
static void
nm_wifi_p2p_peer_class_init (NMWifiP2PPeerClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
object_class->get_property = get_property;
object_class->finalize = finalize;
/**
* NMWifiP2PPeer:flags:
*
* The flags of the P2P peer.
*
* Since: 1.16
**/
obj_properties[PROP_FLAGS] =
g_param_spec_flags (NM_WIFI_P2P_PEER_FLAGS, "", "",
NM_TYPE_802_11_AP_FLAGS,
NM_802_11_AP_FLAGS_NONE,
G_PARAM_READABLE |
G_PARAM_STATIC_STRINGS);
/**
* NMWifiP2PPeer:name:
*
* The name of the P2P peer.
*
* Since: 1.16
**/
obj_properties[PROP_NAME] =
g_param_spec_string (NM_WIFI_P2P_PEER_NAME, "", "",
NULL,
G_PARAM_READABLE |
G_PARAM_STATIC_STRINGS);
/**
* NMWifiP2PPeer:manufacturer:
*
* The manufacturer of the P2P peer.
*
* Since: 1.16
**/
obj_properties[PROP_MANUFACTURER] =
g_param_spec_string (NM_WIFI_P2P_PEER_MANUFACTURER, "", "",
NULL,
G_PARAM_READABLE |
G_PARAM_STATIC_STRINGS);
/**
* NMWifiP2PPeer:model:
*
* The model of the P2P peer.
*
* Since: 1.16
**/
obj_properties[PROP_MODEL] =
g_param_spec_string (NM_WIFI_P2P_PEER_MODEL, "", "",
NULL,
G_PARAM_READABLE |
G_PARAM_STATIC_STRINGS);
/**
* NMWifiP2PPeer:model-number:
*
* The hardware address of the P2P peer.
*
* Since: 1.16
**/
obj_properties[PROP_MODEL_NUMBER] =
g_param_spec_string (NM_WIFI_P2P_PEER_MODEL_NUMBER, "", "",
NULL,
G_PARAM_READABLE |
G_PARAM_STATIC_STRINGS);
/**
* NMWifiP2PPeer:serial:
*
* The serial number of the P2P peer.
*
* Since: 1.16
**/
obj_properties[PROP_SERIAL] =
g_param_spec_string (NM_WIFI_P2P_PEER_SERIAL, "", "",
NULL,
G_PARAM_READABLE |
G_PARAM_STATIC_STRINGS);
/**
* NMWifiP2PPeer:wfd-ies:
*
* The WFD information elements of the P2P peer.
*
* Since: 1.16
**/
obj_properties[PROP_WFD_IES] =
g_param_spec_boxed (NM_WIFI_P2P_PEER_WFD_IES, "", "",
G_TYPE_BYTES,
G_PARAM_READABLE |
G_PARAM_STATIC_STRINGS);
/**
* NMWifiP2PPeer:hw-address:
*
* The hardware address of the P2P peer.
*
* Since: 1.16
**/
obj_properties[PROP_HW_ADDRESS] =
g_param_spec_string (NM_WIFI_P2P_PEER_HW_ADDRESS, "", "",
NULL,
G_PARAM_READABLE |
G_PARAM_STATIC_STRINGS);
/**
* NMWifiP2PPeer:strength:
*
* The current signal strength of the P2P peer.
*
* Since: 1.16
**/
obj_properties[PROP_STRENGTH] =
g_param_spec_uchar (NM_WIFI_P2P_PEER_STRENGTH, "", "",
0, G_MAXUINT8, 0,
G_PARAM_READABLE |
G_PARAM_STATIC_STRINGS);
/**
* NMWifiP2PPeer:last-seen:
*
* The timestamp (in CLOCK_BOOTTIME seconds) for the last time the
* P2P peer was found. A value of -1 means the peer has never been seen.
*
* Since: 1.16
**/
obj_properties[PROP_LAST_SEEN] =
g_param_spec_int (NM_WIFI_P2P_PEER_LAST_SEEN, "", "",
-1, G_MAXINT, -1,
G_PARAM_READABLE |
G_PARAM_STATIC_STRINGS);
_nml_dbus_meta_class_init_with_properties (object_class, &_nml_dbus_meta_iface_nm_wifip2ppeer);
}