Пример #1
0
static gboolean set_connected(gpointer user_data)
{
	struct connman_network *network = user_data;
	struct connman_service *service;

	service = __connman_service_lookup_from_network(network);

	if (network->connected == TRUE) {
		struct connman_element *element;
		enum connman_element_type type = CONNMAN_ELEMENT_TYPE_UNKNOWN;

		switch (network->protocol) {
		case CONNMAN_NETWORK_PROTOCOL_UNKNOWN:
			connman_warn("%s: unknown protocol", __func__);
			return 0;
		case CONNMAN_NETWORK_PROTOCOL_IP:
			type = CONNMAN_ELEMENT_TYPE_DHCP;
			break;
		case CONNMAN_NETWORK_PROTOCOL_PPP:
			type = CONNMAN_ELEMENT_TYPE_PPP;
			break;
		}

		__connman_device_increase_connections(network->device);

		__connman_device_set_network(network->device, network);

		connman_device_set_disconnected(network->device, FALSE);

		element = connman_element_create(NULL);
		if (element != NULL) {
			element->type  = type;
			element->index = network->element.index;

			if (connman_element_register(element,
						&network->element) < 0)
				connman_element_unref(element);

			__connman_service_indicate_state(service,
					CONNMAN_SERVICE_STATE_CONFIGURATION);
		}
	} else {
		connman_element_unregister_children(&network->element);

		__connman_device_set_network(network->device, NULL);
		network->hidden = FALSE;

		__connman_device_decrease_connections(network->device);

		__connman_service_indicate_state(service,
						CONNMAN_SERVICE_STATE_IDLE);
	}

	network->connecting = FALSE;

	connman_network_set_associating(network, FALSE);

	return FALSE;
}
Пример #2
0
static int pan_disconnect(struct connman_network *network)
{
	const char *path = connman_network_get_string(network, "Path");
	DBusMessage *message;
	DBusPendingCall *call;

	DBG("network %p", network);

	if (!path)
		return -EINVAL;

	message = dbus_message_new_method_call(BLUEZ_SERVICE, path,
					BLUEZ_NETWORK_INTERFACE, DISCONNECT);
	if (!message)
		return -ENOMEM;

	dbus_message_set_auto_start(message, FALSE);

	dbus_message_append_args(message, DBUS_TYPE_INVALID);

	if (!dbus_connection_send_with_reply(connection, message,
						&call, TIMEOUT)) {
		connman_error("Failed to disconnect service");
		dbus_message_unref(message);
		return -EINVAL;
	}

	if (!call) {
		connman_error("D-Bus connection not available");
		dbus_message_unref(message);
		return -EINVAL;
	}

	connman_network_ref(network);

	connman_network_set_associating(network, false);

	dbus_pending_call_set_notify(call, disconnect_reply, g_strdup(path),
			g_free);

	dbus_message_unref(message);

	return 0;
}
/**
 * __connman_network_connect:
 * @network: network structure
 *
 * Connect network
 */
int __connman_network_connect(struct connman_network *network)
{
	int err;

	DBG("network %p", network);

	if (network->connected == TRUE)
		return -EISCONN;

	if (network->connecting == TRUE || network->associating == TRUE)
		return -EALREADY;

	if (network->driver == NULL)
		return -EUNATCH;

	if (network->driver->connect == NULL)
		return -ENOSYS;

	if (network->device == NULL)
		return -ENODEV;

	network->connecting = TRUE;

#if defined TIZEN_EXT
	if (network->type != CONNMAN_NETWORK_TYPE_CELLULAR)
#endif
	__connman_device_disconnect(network->device);

	err = network->driver->connect(network);
	if (err < 0) {
		if (err == -EINPROGRESS)
			connman_network_set_associating(network, TRUE);
		else {
			network->connecting = FALSE;
		}

		return err;
	}

	network->connected = TRUE;
	set_connected(network);

	return err;
}
static void set_connected_manual(struct connman_network *network)
{
	struct connman_service *service;
	struct connman_ipconfig *ipconfig;
	int err;

	DBG("network %p", network);

	service = __connman_service_lookup_from_network(network);

	ipconfig = __connman_service_get_ip4config(service);

	if (__connman_ipconfig_get_local(ipconfig) == NULL)
		__connman_service_read_ip4config(service);

	set_configuration(network);

	err = __connman_ipconfig_address_add(ipconfig);
	if (err < 0)
		goto err;

#if defined TIZEN_EXT
/*
 * Description: __connman_service_lookup_from_index cannot find correct service
 */
	err = __connman_ipconfig_gateway_add(ipconfig, service);
#else
	err = __connman_ipconfig_gateway_add(ipconfig);
#endif
	if (err < 0)
		goto err;

	network->connecting = FALSE;

	connman_network_set_associating(network, FALSE);

	return;

err:
	connman_network_set_error(network,
					CONNMAN_NETWORK_ERROR_CONFIGURE_FAIL);
	return;
}
static int set_connected_fixed(struct connman_network *network)
{
	struct connman_service *service;
	struct connman_ipconfig *ipconfig_ipv4;
	int err;

	DBG("");

	service = __connman_service_lookup_from_network(network);

	ipconfig_ipv4 = __connman_service_get_ip4config(service);

	set_configuration(network);

	network->connecting = FALSE;

	connman_network_set_associating(network, FALSE);

	err = __connman_ipconfig_address_add(ipconfig_ipv4);
	if (err < 0)
		goto err;

#if defined TIZEN_EXT
/*
 * Description: __connman_service_lookup_from_index cannot find correct service
 */
	err = __connman_ipconfig_gateway_add(ipconfig_ipv4, service);
#else
	err = __connman_ipconfig_gateway_add(ipconfig_ipv4);
#endif
	if (err < 0)
		goto err;

	return 0;

err:
	connman_network_set_error(network,
			CONNMAN_NETWORK_ERROR_CONFIGURE_FAIL);

	return err;
}
Пример #6
0
static int bluetooth_pan_connect(struct connman_network *network)
{
	struct bluetooth_pan *pan = connman_network_get_data(network);
	const char *path;

	DBG("network %p", network);

	if (!pan)
		return -EINVAL;

	path = g_dbus_proxy_get_path(pan->btnetwork_proxy);

	if (!g_dbus_proxy_method_call(pan->btnetwork_proxy, "Connect",
			pan_connect_append, pan_connect_cb,
			g_strdup(path), g_free))
		return -EIO;

	connman_network_set_associating(pan->network, true);

	return -EINPROGRESS;
}
Пример #7
0
/**
 * __connman_network_connect:
 * @network: network structure
 *
 * Connect network
 */
int __connman_network_connect(struct connman_network *network)
{
	int err;

	_DBG_NETWORK("network %p", network);

	if (network->connected == TRUE)
		return -EISCONN;

	if (network->connecting == TRUE || network->associating == TRUE)
		return -EALREADY;

	if (network->driver == NULL)
		return -EUNATCH;

	if (network->driver->connect == NULL)
		return -ENOSYS;

	__connman_device_disconnect(network->device);

	network->connecting = TRUE;

	err = network->driver->connect(network);
	if (err < 0) {
		if (err == -EINPROGRESS)
			connman_network_set_associating(network, TRUE);
		else
			network->hidden = FALSE;

		return err;
	}

	network->connected = TRUE;
	set_connected(network);

	return err;
}
Пример #8
0
static void pan_connect_cb(DBusMessage *message, void *user_data)
{
	const char *path = user_data;
	const char *iface = NULL;
	struct bluetooth_pan *pan;
	DBusMessageIter iter;

	pan = g_hash_table_lookup(networks, path);
	if (!pan || !pan->network) {
		DBG("network already removed");
		return;
	}

	if (dbus_message_get_type(message) == DBUS_MESSAGE_TYPE_ERROR) {
		const char *dbus_error = dbus_message_get_error_name(message);

		DBG("network %p %s", pan->network, dbus_error);

		if (strcmp(dbus_error,
				"org.bluez.Error.AlreadyConnected") != 0) {
			connman_network_set_associating(pan->network, false);
			connman_network_set_error(pan->network,
				CONNMAN_NETWORK_ERROR_ASSOCIATE_FAIL);
			return;
		}
	} else {
		if (dbus_message_iter_init(message, &iter) &&
				dbus_message_iter_get_arg_type(&iter) ==
				DBUS_TYPE_STRING)
			dbus_message_iter_get_basic(&iter, &iface);
	}

	DBG("network %p interface %s", pan->network, iface);

	pan_connect(pan, iface);
}
Пример #9
0
static gboolean network_changed(DBusConnection *conn,
				DBusMessage *message, void *user_data)
{
	const char *path = dbus_message_get_path(message);
	struct connman_network *network;
	DBusMessageIter iter, value;
	const char *key;

	DBG("path %s", path);

	network = g_hash_table_lookup(bluetooth_networks, path);
	if (network == NULL)
		return TRUE;

	if (dbus_message_iter_init(message, &iter) == FALSE)
		return TRUE;

	dbus_message_iter_get_basic(&iter, &key);

	dbus_message_iter_next(&iter);
	dbus_message_iter_recurse(&iter, &value);

	if (g_str_equal(key, "Connected") == TRUE) {
		dbus_bool_t connected;

		dbus_message_iter_get_basic(&value, &connected);

		if (connected == TRUE)
			return TRUE;

		connman_network_set_associating(network, FALSE);
		connman_network_set_connected(network, FALSE);
	}

	return TRUE;
}
Пример #10
0
static void state_change(struct supplicant_task *task, DBusMessage *msg)
{
	DBusError error;
	const char *newstate, *oldstate;
	unsigned char bssid[ETH_ALEN];
	unsigned int bssid_len;
	enum supplicant_state state, ostate;

	dbus_error_init(&error);

	if (dbus_message_get_args(msg, &error, DBUS_TYPE_STRING, &newstate,
						DBUS_TYPE_STRING, &oldstate,
						DBUS_TYPE_INVALID) == FALSE) {
		if (dbus_error_is_set(&error) == TRUE) {
			connman_error("%s", error.message);
			dbus_error_free(&error);
		} else
			connman_error("Wrong arguments for state change");
		return;
	}

	connman_info("%s state change %s -> %s%s", task->ifname,
			oldstate, newstate,
			task->scanning == TRUE ? " (scanning)" : "");

	state = string2state(newstate);
	if (state == WPA_INVALID)
		return;

	if (task->scanning == TRUE && state != WPA_SCANNING) {
		connman_device_set_scanning(task->device, FALSE);
		task->scanning = FALSE;
	}

	ostate = task->state;
	task->state = state;

	if (task->network == NULL)
		return;

	switch (task->state) {
	case WPA_COMPLETED:
		if (ostate != WPA_ASSOCIATED && ostate != WPA_GROUP_HANDSHAKE)
			goto badstate;

		/* reset bg scan reschedule */
		connman_device_reset_scan(task->device);

		if (get_bssid(task->device, bssid, &bssid_len) == 0)
			connman_network_set_address(task->network,
							bssid, bssid_len);

		/* carrier on */
		connman_network_set_connected(task->network, TRUE);
		break;

	case WPA_ASSOCIATING:
		if (ostate != WPA_SCANNING && ostate != WPA_COMPLETED)
			goto badstate;

		if (ostate == WPA_SCANNING)
			connman_network_set_associating(task->network, TRUE);
		break;

	case WPA_INACTIVE:
		if (ostate != WPA_SCANNING && ostate != WPA_DISCONNECTED)
			goto badstate;
		/* fall thru... */
	case WPA_DISCONNECTED:
		/* carrier off */
		connman_network_set_connected(task->network, FALSE);

		if (task->disconnecting == TRUE) {
			connman_network_unref(task->network);
			task->disconnecting = FALSE;

			if (task->pending_network != NULL) {
				task->network = task->pending_network;
				task->pending_network = NULL;
				task_connect(task);
			} else
				task->network = NULL;
		}
		break;

	default:
		connman_network_set_associating(task->network, FALSE);
		break;
	}
	return;
badstate:
	connman_error("%s invalid state change %s -> %s%s", task->ifname,
			oldstate, newstate,
			task->scanning == TRUE ? " (scanning)" : "");
}
static gboolean set_connected(gpointer user_data)
{
	struct connman_network *network = user_data;
	struct connman_service *service;
	struct connman_ipconfig *ipconfig_ipv4, *ipconfig_ipv6;
	enum connman_ipconfig_method ipv4_method, ipv6_method;

	service = __connman_service_lookup_from_network(network);

	ipconfig_ipv4 = __connman_service_get_ip4config(service);
	ipconfig_ipv6 = __connman_service_get_ip6config(service);

	DBG("service %p ipv4 %p ipv6 %p", service, ipconfig_ipv4,
		ipconfig_ipv6);

	ipv4_method = __connman_ipconfig_get_method(ipconfig_ipv4);
	ipv6_method = __connman_ipconfig_get_method(ipconfig_ipv6);

	DBG("method ipv4 %d ipv6 %d", ipv4_method, ipv6_method);
	DBG("network connected %d", network->connected);

	if (network->connected == TRUE) {
		int ret;

		switch (ipv6_method) {
		case CONNMAN_IPCONFIG_METHOD_UNKNOWN:
		case CONNMAN_IPCONFIG_METHOD_OFF:
			break;
		case CONNMAN_IPCONFIG_METHOD_AUTO:
			autoconf_ipv6_set(network);
			break;
		case CONNMAN_IPCONFIG_METHOD_FIXED:
		case CONNMAN_IPCONFIG_METHOD_MANUAL:
			ret = manual_ipv6_set(network, ipconfig_ipv6);
			if (ret != 0) {
				connman_network_set_error(network,
					CONNMAN_NETWORK_ERROR_ASSOCIATE_FAIL);
				return FALSE;
			}
			break;
		case CONNMAN_IPCONFIG_METHOD_DHCP:
			break;
		}

		switch (ipv4_method) {
		case CONNMAN_IPCONFIG_METHOD_UNKNOWN:
		case CONNMAN_IPCONFIG_METHOD_OFF:
		case CONNMAN_IPCONFIG_METHOD_AUTO:
			return FALSE;
		case CONNMAN_IPCONFIG_METHOD_FIXED:
			if (set_connected_fixed(network) < 0) {
				connman_network_set_error(network,
					CONNMAN_NETWORK_ERROR_ASSOCIATE_FAIL);
				return FALSE;
			}
			return TRUE;
		case CONNMAN_IPCONFIG_METHOD_MANUAL:
			set_connected_manual(network);
			return TRUE;
		case CONNMAN_IPCONFIG_METHOD_DHCP:
			if (set_connected_dhcp(network) < 0) {
				connman_network_set_error(network,
					CONNMAN_NETWORK_ERROR_ASSOCIATE_FAIL);
				return FALSE;
			}
		}

	} else {
		enum connman_service_state state;

		__connman_device_set_network(network->device, NULL);

		switch (ipv4_method) {
		case CONNMAN_IPCONFIG_METHOD_UNKNOWN:
		case CONNMAN_IPCONFIG_METHOD_OFF:
		case CONNMAN_IPCONFIG_METHOD_AUTO:
		case CONNMAN_IPCONFIG_METHOD_FIXED:
		case CONNMAN_IPCONFIG_METHOD_MANUAL:
			break;
		case CONNMAN_IPCONFIG_METHOD_DHCP:
			__connman_dhcp_stop(network);
			break;
		}

		/*
		 * We only set the disconnect state if we were not in idle
		 * or in failure. It does not make sense to go to disconnect
		 * state if we were not connected.
		 */
		state = __connman_service_ipconfig_get_state(service,
						CONNMAN_IPCONFIG_TYPE_IPV4);
		if (state != CONNMAN_SERVICE_STATE_IDLE &&
					state != CONNMAN_SERVICE_STATE_FAILURE)
			__connman_service_ipconfig_indicate_state(service,
					CONNMAN_SERVICE_STATE_DISCONNECT,
					CONNMAN_IPCONFIG_TYPE_IPV4);

		state = __connman_service_ipconfig_get_state(service,
						CONNMAN_IPCONFIG_TYPE_IPV6);
		if (state != CONNMAN_SERVICE_STATE_IDLE &&
					state != CONNMAN_SERVICE_STATE_FAILURE)
			__connman_service_ipconfig_indicate_state(service,
					CONNMAN_SERVICE_STATE_DISCONNECT,
					CONNMAN_IPCONFIG_TYPE_IPV6);

		__connman_connection_gateway_remove(service,
						CONNMAN_IPCONFIG_TYPE_ALL);

		__connman_ipconfig_address_unset(ipconfig_ipv4);
		__connman_ipconfig_address_unset(ipconfig_ipv6);

		/*
		 * Special handling for IPv6 autoconfigured address.
		 * The simplest way to remove autoconfigured routes is to
		 * disable IPv6 temporarily so that kernel will do the cleanup
		 * automagically.
		 */
		if (ipv6_method == CONNMAN_IPCONFIG_METHOD_AUTO) {
			__connman_ipconfig_disable_ipv6(ipconfig_ipv6);
			__connman_ipconfig_enable_ipv6(ipconfig_ipv6);
		}

#if defined TIZEN_EXT
		if (connman_service_get_type(service) ==
				CONNMAN_SERVICE_TYPE_CELLULAR) {
			network->connecting = FALSE;
			connman_network_set_associating(network, FALSE);
		}
#endif
		__connman_service_ipconfig_indicate_state(service,
					CONNMAN_SERVICE_STATE_IDLE,
					CONNMAN_IPCONFIG_TYPE_IPV4);

		__connman_service_ipconfig_indicate_state(service,
					CONNMAN_SERVICE_STATE_IDLE,
					CONNMAN_IPCONFIG_TYPE_IPV6);
#if defined TIZEN_EXT
		if (connman_service_get_type(service) ==
				CONNMAN_SERVICE_TYPE_CELLULAR)
			return FALSE;
#endif
	}

	network->connecting = FALSE;

	connman_network_set_associating(network, FALSE);

	return FALSE;
}