Esempio n. 1
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 == NULL) {
		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_error(pan->network,
				CONNMAN_NETWORK_ERROR_ASSOCIATE_FAIL);
			return;
		}
	} else {
		if (dbus_message_iter_init(message, &iter) == TRUE &&
				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);
}
static int manual_ipv4_set(struct connman_network *network,
				struct connman_ipconfig *ipconfig)
{
	struct connman_service *service;
	int err;

	service = __connman_service_lookup_from_network(network);
	if (service == NULL)
		return -EINVAL;

	err = __connman_ipconfig_address_add(ipconfig);
	if (err < 0) {
		connman_network_set_error(network,
			CONNMAN_NETWORK_ERROR_CONFIGURE_FAIL);
		return err;
	}

#if defined TIZEN_EXT
/*
 * Description: __connman_service_lookup_from_index cannot find correct service
 */
	return __connman_ipconfig_gateway_add(ipconfig, service);
#else
	return __connman_ipconfig_gateway_add(ipconfig);
#endif
}
int __connman_network_set_ipconfig(struct connman_network *network,
					struct connman_ipconfig *ipconfig_ipv4,
					struct connman_ipconfig *ipconfig_ipv6)
{
	enum connman_ipconfig_method method;
	int ret;

	if (network == NULL)
		return -EINVAL;

	if (ipconfig_ipv6) {
		method = __connman_ipconfig_get_method(ipconfig_ipv6);

		switch (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 ret;
			}
			break;
		case CONNMAN_IPCONFIG_METHOD_DHCP:
			break;
		}
	}

	if (ipconfig_ipv4) {
		method = __connman_ipconfig_get_method(ipconfig_ipv4);

		switch (method) {
		case CONNMAN_IPCONFIG_METHOD_UNKNOWN:
		case CONNMAN_IPCONFIG_METHOD_OFF:
		case CONNMAN_IPCONFIG_METHOD_FIXED:
		case CONNMAN_IPCONFIG_METHOD_AUTO:
			return -EINVAL;
		case CONNMAN_IPCONFIG_METHOD_MANUAL:
			return manual_ipv4_set(network, ipconfig_ipv4);
		case CONNMAN_IPCONFIG_METHOD_DHCP:
			return __connman_dhcp_start(network, dhcp_callback);
		}
	}

	return 0;
}
static int manual_ipv6_set(struct connman_network *network,
				struct connman_ipconfig *ipconfig_ipv6)
{
	struct connman_service *service;
	int err;

	DBG("network %p ipv6 %p", network, ipconfig_ipv6);

	service = __connman_service_lookup_from_network(network);
	if (service == NULL)
		return -EINVAL;

	if (__connman_ipconfig_get_local(ipconfig_ipv6) == NULL)
		__connman_service_read_ip6config(service);

	err = __connman_ipconfig_address_add(ipconfig_ipv6);
	if (err < 0) {
		connman_network_set_error(network,
			CONNMAN_NETWORK_ERROR_CONFIGURE_FAIL);
		return err;
	}

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

	__connman_connection_gateway_activate(service,
						CONNMAN_IPCONFIG_TYPE_IPV6);

	__connman_device_set_network(network->device, network);

	connman_device_set_disconnected(network->device, FALSE);

	network->connecting = FALSE;

	return 0;
}
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;
}
/**
 * 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;
}
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;
}