int __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_connecting(network) == TRUE) { /* * Skip network in the process of connecting. * This is a workaround for WiFi networks serviced * by the supplicant plugin that hold a reference * to the network. If we disconnect the network * here then the referenced object will not be * registered and usage (like launching DHCP client) * will fail. There is nothing to be gained by * removing the network here anyway. */ connman_warn("Skipping disconnect of %s, network is connecting.", connman_network_get_identifier(network)); continue; } __connman_network_disconnect(network); } return 0; }
/** * connman_network_set_connected: * @network: network structure * @connected: connected state * * Change connected state of network */ int connman_network_set_connected(struct connman_network *network, connman_bool_t connected) { DBusMessage *signal; DBusMessageIter entry, value; const char *key = "Connected"; _DBG_NETWORK("network %p connected %d", network, connected); if ((network->connecting == TRUE || network->associating == TRUE) && connected == FALSE) { connman_element_set_error(&network->element, CONNMAN_ELEMENT_ERROR_CONNECT_FAILED); __connman_network_disconnect(network); } if (network->connected == connected) { _DBG_NETWORK("%s: already %sconnected", __func__, connected ? "" : "!"); return -EALREADY; } network->connected = connected; if (network->registered == FALSE) { _DBG_NETWORK("not registered; defer"); g_idle_add(set_connected, network); return 0; } signal = dbus_message_new_signal(network->element.path, CONNMAN_NETWORK_INTERFACE, "PropertyChanged"); if (signal == NULL) { connman_error("%s: cannot allocate signal", __func__); /* XXX? defer to idle loop */ return 0; } dbus_message_iter_init_append(signal, &entry); dbus_message_iter_append_basic(&entry, DBUS_TYPE_STRING, &key); dbus_message_iter_open_container(&entry, DBUS_TYPE_VARIANT, DBUS_TYPE_BOOLEAN_AS_STRING, &value); dbus_message_iter_append_basic(&value, DBUS_TYPE_BOOLEAN, &connected); dbus_message_iter_close_container(&entry, &value); g_dbus_send_message(connection, signal); set_connected(network); return 0; }
/** * connman_network_set_connected: * @network: network structure * @connected: connected state * * Change connected state of network */ int connman_network_set_connected(struct connman_network *network, connman_bool_t connected) { DBG("network %p connected %d", network, connected); if ((network->connecting == TRUE || network->associating == TRUE) && connected == FALSE) { connman_network_set_error(network, CONNMAN_NETWORK_ERROR_CONNECT_FAIL); __connman_network_disconnect(network); } if (network->connected == connected) return -EALREADY; network->connected = connected; set_connected(network); return 0; }