mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager.git
synced 2026-02-25 13:00:28 +01:00
wifi: allow concurrent P2P and station operation
Check interface combination capabilities before activation using the new nm_platform_wifi_can_concurrent() API. If hardware supports concurrency: 1. P2P Device: Log the capability. 2. Wi-Fi Device: Prevent the Station interface from being marked as unavailable when the supplicant state fluctuates during P2P operations. This ensures the infrastructure connection is not torn down when a P2P connection is established on capable hardware.
This commit is contained in:
parent
716efd5377
commit
ffde9ce3de
3 changed files with 62 additions and 8 deletions
|
|
@ -53,6 +53,9 @@ typedef struct {
|
|||
guint peer_dump_id;
|
||||
guint peer_missing_id;
|
||||
|
||||
/* Parent Wi-Fi device ifindex for checking interface combination capabilities */
|
||||
int parent_ifindex;
|
||||
|
||||
bool is_waiting_for_supplicant : 1;
|
||||
bool enabled : 1;
|
||||
} NMDeviceWifiP2PPrivate;
|
||||
|
|
@ -365,6 +368,32 @@ act_stage1_prepare(NMDevice *device, NMDeviceStateReason *out_failure_reason)
|
|||
return NM_ACT_STAGE_RETURN_FAILURE;
|
||||
}
|
||||
|
||||
/* Check if the hardware supports concurrent Station + P2P operation.
|
||||
* We use NL80211_IFTYPE_STATION (2) and NL80211_IFTYPE_P2P_CLIENT (8).
|
||||
* If concurrency is not supported, log a warning but proceed anyway
|
||||
* (the kernel/supplicant will handle the actual switching).
|
||||
*/
|
||||
if (priv->parent_ifindex > 0) {
|
||||
guint8 num_channels = 0;
|
||||
gboolean can_concurrent;
|
||||
|
||||
can_concurrent = nm_platform_wifi_can_concurrent(NM_PLATFORM_GET,
|
||||
priv->parent_ifindex,
|
||||
NM_WIFI_IFACE_TYPE_STATION,
|
||||
NM_WIFI_IFACE_TYPE_P2P_CLIENT,
|
||||
&num_channels);
|
||||
|
||||
if (can_concurrent) {
|
||||
_LOGI(LOGD_DEVICE | LOGD_WIFI,
|
||||
"P2P: Hardware supports concurrent Station + P2P operation (channels: %u)",
|
||||
num_channels);
|
||||
} else {
|
||||
_LOGW(LOGD_DEVICE | LOGD_WIFI,
|
||||
"P2P: Hardware may not support concurrent Station + P2P operation. "
|
||||
"Infrastructure connection may be interrupted.");
|
||||
}
|
||||
}
|
||||
|
||||
connection = nm_device_get_applied_connection(NM_DEVICE(self));
|
||||
g_return_val_if_fail(connection, NM_ACT_STAGE_RETURN_FAILURE);
|
||||
|
||||
|
|
@ -1158,7 +1187,9 @@ nm_device_wifi_p2p_get_mgmt_iface(NMDeviceWifiP2P *self)
|
|||
}
|
||||
|
||||
void
|
||||
nm_device_wifi_p2p_set_mgmt_iface(NMDeviceWifiP2P *self, NMSupplicantInterface *iface)
|
||||
nm_device_wifi_p2p_set_mgmt_iface(NMDeviceWifiP2P *self,
|
||||
NMSupplicantInterface *iface,
|
||||
int parent_ifindex)
|
||||
{
|
||||
NMDeviceWifiP2PPrivate *priv;
|
||||
|
||||
|
|
@ -1172,14 +1203,17 @@ nm_device_wifi_p2p_set_mgmt_iface(NMDeviceWifiP2P *self, NMSupplicantInterface *
|
|||
|
||||
supplicant_interfaces_release(self, FALSE);
|
||||
|
||||
if (!iface)
|
||||
if (!iface) {
|
||||
priv->parent_ifindex = 0;
|
||||
goto done;
|
||||
}
|
||||
|
||||
_LOGD(LOGD_DEVICE | LOGD_WIFI,
|
||||
"P2P: WPA supplicant management interface changed to %s.",
|
||||
nm_ref_string_get_str(nm_supplicant_interface_get_object_path(iface)));
|
||||
|
||||
priv->mgmt_iface = g_object_ref(iface);
|
||||
priv->mgmt_iface = g_object_ref(iface);
|
||||
priv->parent_ifindex = parent_ifindex;
|
||||
|
||||
g_signal_connect(priv->mgmt_iface,
|
||||
NM_SUPPLICANT_INTERFACE_STATE,
|
||||
|
|
|
|||
|
|
@ -31,7 +31,9 @@ GType nm_device_wifi_p2p_get_type(void);
|
|||
NMDeviceWifiP2P *nm_device_wifi_p2p_new(const char *iface);
|
||||
|
||||
NMSupplicantInterface *nm_device_wifi_p2p_get_mgmt_iface(NMDeviceWifiP2P *self);
|
||||
void nm_device_wifi_p2p_set_mgmt_iface(NMDeviceWifiP2P *self, NMSupplicantInterface *iface);
|
||||
void nm_device_wifi_p2p_set_mgmt_iface(NMDeviceWifiP2P *self,
|
||||
NMSupplicantInterface *iface,
|
||||
int parent_ifindex);
|
||||
|
||||
void nm_device_wifi_p2p_remove(NMDeviceWifiP2P *self);
|
||||
|
||||
|
|
|
|||
|
|
@ -702,7 +702,7 @@ supplicant_interface_release(NMDeviceWifi *self)
|
|||
|
||||
if (priv->p2p_device) {
|
||||
/* Signal to P2P device to also release its reference */
|
||||
nm_device_wifi_p2p_set_mgmt_iface(priv->p2p_device, NULL);
|
||||
nm_device_wifi_p2p_set_mgmt_iface(priv->p2p_device, NULL, 0);
|
||||
}
|
||||
|
||||
_scan_notify_is_scanning(self);
|
||||
|
|
@ -1344,8 +1344,22 @@ is_available(NMDevice *device, NMDeviceCheckDevAvailableFlags flags)
|
|||
|
||||
supplicant_state = nm_supplicant_interface_get_state(priv->sup_iface);
|
||||
if (supplicant_state <= NM_SUPPLICANT_INTERFACE_STATE_STARTING
|
||||
|| supplicant_state > NM_SUPPLICANT_INTERFACE_STATE_COMPLETED)
|
||||
|| supplicant_state > NM_SUPPLICANT_INTERFACE_STATE_COMPLETED) {
|
||||
guint8 num_channels = 0;
|
||||
|
||||
if (nm_platform_wifi_can_concurrent(nm_device_get_platform(device),
|
||||
nm_device_get_ifindex(device),
|
||||
NM_WIFI_IFACE_TYPE_STATION,
|
||||
NM_WIFI_IFACE_TYPE_P2P_CLIENT,
|
||||
&num_channels)) {
|
||||
_LOGI(LOGD_DEVICE | LOGD_WIFI,
|
||||
"Device is available (state %d) due to hardware concurrency support",
|
||||
supplicant_state);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
|
@ -2749,7 +2763,9 @@ recheck_p2p_availability(NMDeviceWifi *self)
|
|||
|
||||
priv->p2p_device = nm_device_wifi_p2p_new(iface_name);
|
||||
|
||||
nm_device_wifi_p2p_set_mgmt_iface(priv->p2p_device, priv->sup_iface);
|
||||
nm_device_wifi_p2p_set_mgmt_iface(priv->p2p_device,
|
||||
priv->sup_iface,
|
||||
nm_device_get_ifindex(NM_DEVICE(self)));
|
||||
|
||||
g_signal_emit(self, signals[P2P_DEVICE_CREATED], 0, priv->p2p_device);
|
||||
g_object_add_weak_pointer(G_OBJECT(priv->p2p_device), (gpointer *) &priv->p2p_device);
|
||||
|
|
@ -2758,7 +2774,9 @@ recheck_p2p_availability(NMDeviceWifi *self)
|
|||
}
|
||||
|
||||
if (p2p_available && priv->p2p_device) {
|
||||
nm_device_wifi_p2p_set_mgmt_iface(priv->p2p_device, priv->sup_iface);
|
||||
nm_device_wifi_p2p_set_mgmt_iface(priv->p2p_device,
|
||||
priv->sup_iface,
|
||||
nm_device_get_ifindex(NM_DEVICE(self)));
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue