+void __connman_device_disconnect(struct connman_device *device)
+{
+ GHashTableIter iter;
+ gpointer key, value;
+
+ DBG("device %p", device);
+
+ connman_device_set_disconnected(device, TRUE);
+
+ g_hash_table_iter_init(&iter, device->networks);
+
+ while (g_hash_table_iter_next(&iter, &key, &value) == TRUE) {
+ struct connman_network *network = value;
+
+ if (connman_network_get_connected(network) == TRUE)
+ __connman_network_disconnect(network);
+ }
+}
+
+static void connect_known_network(struct connman_device *device)
+{
+ struct connman_network *network = NULL;
+ GHashTableIter iter;
+ gpointer key, value;
+ unsigned int count = 0;
+
+ DBG("device %p", device);
+
+ g_hash_table_iter_init(&iter, device->networks);
+
+ while (g_hash_table_iter_next(&iter, &key, &value) == TRUE) {
+ connman_uint8_t old_priority, new_priority;
+ connman_uint8_t old_strength, new_strength;
+ const char *name;
+
+ count++;
+
+ name = connman_network_get_string(value, "Name");
+ if (name != NULL && device->last_network != NULL) {
+ if (g_str_equal(name, device->last_network) == TRUE) {
+ network = value;
+ break;
+ }
+ }
+
+ if (connman_network_get_remember(value) == FALSE)
+ continue;
+
+ if (network == NULL) {
+ network = value;
+ continue;
+ }
+
+ old_priority = connman_network_get_uint8(network, "Priority");
+ new_priority = connman_network_get_uint8(value, "Priority");
+
+ if (new_priority != old_priority) {
+ if (new_priority > old_priority)
+ network = value;
+ continue;
+ }
+
+ old_strength = connman_network_get_uint8(network, "Strength");
+ new_strength = connman_network_get_uint8(value, "Strength");
+
+ if (new_strength > old_strength)
+ network = value;
+ }
+
+ if (network != NULL) {
+ int err;
+
+ err = connman_network_connect(network);
+ if (err == 0 || err == -EINPROGRESS)
+ return;
+ }
+
+ if (count > 0)
+ return;
+
+ if (device->driver && device->driver->scan)
+ device->driver->scan(device);
+}
+
+static void mark_network_unavailable(gpointer key, gpointer value,
+ gpointer user_data)
+{
+ struct connman_network *network = value;
+
+ if (connman_network_get_connected(network) == TRUE)
+ return;
+
+ connman_network_set_available(network, FALSE);
+}
+
+static gboolean remove_unavailable_network(gpointer key, gpointer value,
+ gpointer user_data)
+{
+ struct connman_network *network = value;
+
+ if (connman_network_get_connected(network) == TRUE)
+ return FALSE;
+
+ if (connman_network_get_remember(network) == TRUE)
+ return FALSE;
+
+ if (connman_network_get_available(network) == TRUE)
+ return FALSE;
+
+ return TRUE;
+}
+