}
/**
- * nm_device_get_available_connections:
+ * nm_device_get_best_connection:
* @self: the #NMDevice
* @specific_object: a specific object path if any
+ * @error: reason why no connection was returned
*
- * Returns a list of connections available to activate on the device, taking
- * into account any device-specific details given by @specific_object (like
- * WiFi access point path).
+ * Returns a connection that's most suitable for user-initiated activation
+ * of a device, optionally with a given specific object.
*
- * Returns: caller-owned #GPtrArray of #NMConnections
+ * Returns: the #NMSettingsConnection or %NULL (setting an @error)
*/
-GPtrArray *
-nm_device_get_available_connections (NMDevice *self, const char *specific_object)
+NMSettingsConnection *
+nm_device_get_best_connection (NMDevice *self,
+ const char *specific_object,
+ GError **error)
{
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
+ NMSettingsConnection *connection = NULL;
+ NMSettingsConnection *candidate;
+ guint64 best_timestamp = 0;
GHashTableIter iter;
- guint num_available;
- NMConnection *connection = NULL;
- GPtrArray *array = NULL;
- num_available = g_hash_table_size (priv->available_connections);
- if (num_available > 0) {
- array = g_ptr_array_sized_new (num_available);
- g_hash_table_iter_init (&iter, priv->available_connections);
- while (g_hash_table_iter_next (&iter, (gpointer) &connection, NULL)) {
- /* If a specific object is given, only include connections that are
- * compatible with it.
- */
- if ( !specific_object /* << Optimization: we know that the connection is available without @specific_object. */
- || nm_device_check_connection_available (self, connection, _NM_DEVICE_CHECK_CON_AVAILABLE_FOR_USER_REQUEST, specific_object))
- g_ptr_array_add (array, connection);
+ g_hash_table_iter_init (&iter, priv->available_connections);
+ while (g_hash_table_iter_next (&iter, (gpointer) &candidate, NULL)) {
+ guint64 candidate_timestamp = 0;
+
+ /* If a specific object is given, only include connections that are
+ * compatible with it.
+ */
+ if ( specific_object /* << Optimization: we know that the connection is available without @specific_object. */
+ && !nm_device_check_connection_available (self,
+ NM_CONNECTION (candidate),
+ _NM_DEVICE_CHECK_CON_AVAILABLE_FOR_USER_REQUEST,
+ specific_object))
+ continue;
+
+ nm_settings_connection_get_timestamp (candidate, &candidate_timestamp);
+ if (!connection || (candidate_timestamp > best_timestamp)) {
+ connection = candidate;
+ best_timestamp = candidate_timestamp;
}
}
- return array;
+
+ if (!connection) {
+ g_set_error (error, NM_MANAGER_ERROR, NM_MANAGER_ERROR_UNKNOWN_CONNECTION,
+ "The device '%s' has no connections available for activation.",
+ nm_device_get_iface (self));
+ }
+
+ return connection;
}
static void
gboolean nm_device_remove_pending_action (NMDevice *device, const char *action, gboolean assert_is_pending);
gboolean nm_device_has_pending_action (NMDevice *device);
-GPtrArray *nm_device_get_available_connections (NMDevice *device,
- const char *specific_object);
+NMSettingsConnection *nm_device_get_best_connection (NMDevice *device,
+ const char *specific_object,
+ GError **error);
gboolean nm_device_check_connection_available (NMDevice *device,
NMConnection *connection,
* regardless of whether that connection is autoconnect-enabled or not
* (since this is an explicit request, not an auto-activation request).
*/
- if (!connection_path) {
- GPtrArray *available;
- guint64 best_timestamp = 0;
- guint i;
-
+ if (connection_path) {
+ connection = nm_settings_get_connection_by_path (priv->settings, connection_path);
+ if (!connection) {
+ error = g_error_new_literal (NM_MANAGER_ERROR,
+ NM_MANAGER_ERROR_UNKNOWN_CONNECTION,
+ "Connection could not be found.");
+ goto error;
+ }
+ } else {
/* If no connection is given, find a suitable connection for the given device path */
if (!device_path) {
error = g_error_new_literal (NM_MANAGER_ERROR, NM_MANAGER_ERROR_UNKNOWN_DEVICE,
goto error;
}
- available = nm_device_get_available_connections (device, specific_object_path);
- for (i = 0; available && i < available->len; i++) {
- NMSettingsConnection *candidate = g_ptr_array_index (available, i);
- guint64 candidate_timestamp = 0;
-
- nm_settings_connection_get_timestamp (candidate, &candidate_timestamp);
- if (!connection_path || (candidate_timestamp > best_timestamp)) {
- connection_path = nm_connection_get_path (NM_CONNECTION (candidate));
- best_timestamp = candidate_timestamp;
- }
- }
-
- if (available)
- g_ptr_array_free (available, TRUE);
-
- if (!connection_path) {
- error = g_error_new_literal (NM_MANAGER_ERROR,
- NM_MANAGER_ERROR_UNKNOWN_CONNECTION,
- "The device has no connections available.");
+ connection = nm_device_get_best_connection (device, specific_object_path, &error);
+ if (!connection)
goto error;
- }
- }
-
- g_assert (connection_path);
- connection = nm_settings_get_connection_by_path (priv->settings, connection_path);
- if (!connection) {
- error = g_error_new_literal (NM_MANAGER_ERROR,
- NM_MANAGER_ERROR_UNKNOWN_CONNECTION,
- "Connection could not be found.");
- goto error;
}
subject = validate_activation_request (self,