Exemplo n.º 1
0
int supplicant_stop(struct connman_device *device)
{
	int index = connman_device_get_index(device);
	struct supplicant_task *task;

	_DBG_SUPPLICANT("device %p", device);

	task = find_task_by_index(index);
	if (task == NULL)
		return -ENODEV;

	g_free(task->range);

	task_list = g_slist_remove(task_list, task);

	if (task->scan_call != NULL) {
		dbus_pending_call_cancel(task->scan_call);
		task->scan_call = NULL;
	}

	if (task->result_call != NULL) {
		dbus_pending_call_cancel(task->result_call);
		task->result_call = NULL;
	}

	if (task->scanning == TRUE)
		connman_device_set_scanning(task->device, FALSE);

	remove_network(task);

	disconnect_network(task);

	return remove_interface(task);
}
Exemplo n.º 2
0
static void get_properties(struct supplicant_task *task)
{
	DBusMessage *message;
	char *path;

	path = g_slist_nth_data(task->scan_results, 0);
	if (path == NULL)
		goto noscan;

	message = dbus_message_new_method_call(SUPPLICANT_NAME, path,
						SUPPLICANT_INTF ".BSSID",
								"properties");

	task->scan_results = g_slist_remove(task->scan_results, path);
	g_free(path);

	if (message == NULL)
		goto noscan;

	dbus_message_set_auto_start(message, FALSE);

	if (dbus_connection_send_with_reply(connection, message,
				&task->result_call, TIMEOUT) == FALSE) {
		connman_error("Failed to get network properties");
		dbus_message_unref(message);
		goto noscan;
	}

	if (task->result_call == NULL) {
		connman_error("D-Bus connection not available");
		dbus_message_unref(message);
		goto noscan;
	}

	dbus_pending_call_set_notify(task->result_call,
					properties_reply, task, NULL);

	dbus_message_unref(message);

	return;

noscan:
	task->result_call = NULL;

	if (task->scanning == TRUE) {
		connman_device_set_scanning(task->device, FALSE);
		task->scanning = FALSE;
	}
}
Exemplo n.º 3
0
static void scan_reply(DBusPendingCall *call, void *user_data)
{
	struct supplicant_task *task = user_data;
	DBusMessage *reply;

	_DBG_SUPPLICANT("task %p", task);

	task->scan_call = NULL;

	reply = dbus_pending_call_steal_reply(call);
	if (reply == NULL)
		return;

	if (dbus_message_get_type(reply) == DBUS_MESSAGE_TYPE_ERROR) {
		connman_device_set_scanning(task->device, FALSE);
		goto done;
	}

	if (task->scanning == TRUE)
		connman_device_set_scanning(task->device, TRUE);

done:
	dbus_message_unref(reply);
}
Exemplo n.º 4
0
static gboolean adapter_changed(DBusConnection *conn,
				DBusMessage *message, void *user_data)
{
	const char *path = dbus_message_get_path(message);
	struct connman_device *device;
	DBusMessageIter iter, value;
	const char *key;

	DBG("path %s", path);

	device = g_hash_table_lookup(bluetooth_devices, path);
	if (device == 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, "Powered") == TRUE) {
		dbus_bool_t val;

		dbus_message_iter_get_basic(&value, &val);
		connman_device_set_powered(device, val);
		if (val == TRUE)
			check_pending_networks(path);
	} else if (g_str_equal(key, "Discovering") == TRUE) {
		dbus_bool_t val;

		dbus_message_iter_get_basic(&value, &val);
		connman_device_set_scanning(device, val);
	} else if (g_str_equal(key, "Devices") == TRUE) {
		check_networks(&value);
	}

	return TRUE;
}
Exemplo n.º 5
0
int supplicant_scan(struct connman_device *device)
{
	int index = connman_device_get_index(device);
	struct supplicant_task *task;
	int err;

	_DBG_SUPPLICANT("device %p", device);

	task = find_task_by_index(index);
	if (task == NULL)
		return -ENODEV;

	switch (task->state) {
	case WPA_SCANNING:
		return -EALREADY;
	case WPA_ASSOCIATING:
	case WPA_ASSOCIATED:
	case WPA_4WAY_HANDSHAKE:
	case WPA_GROUP_HANDSHAKE:
		return -EBUSY;
	default:
		break;
	}

	task->scanning = TRUE;

	err = initiate_scan(task);
	if (err < 0) {
		if (err == -EINPROGRESS)
			return 0;

		task->scanning = FALSE;
		return err;
	}

	connman_device_set_scanning(task->device, TRUE);

	return 0;
}
Exemplo n.º 6
0
static void scan_results_available(struct supplicant_task *task)
{
	DBusMessage *message;

	_DBG_SUPPLICANT("task %p", task);

	if (task->result_call != NULL)
		return;

	message = dbus_message_new_method_call(SUPPLICANT_NAME, task->path,
						SUPPLICANT_INTF ".Interface",
							"scanResults");
	if (message == NULL)
		return;

	dbus_message_set_auto_start(message, FALSE);

	if (dbus_connection_send_with_reply(connection, message,
				&task->result_call, TIMEOUT) == FALSE) {
		connman_error("Failed to request scan result");
		goto done;
	}

	if (task->result_call == NULL) {
		connman_error("D-Bus connection not available");
		goto done;
	}

	if (task->scanning == TRUE)
		connman_device_set_scanning(task->device, TRUE);

	dbus_pending_call_set_notify(task->result_call,
					scan_results_reply, task, NULL);

done:
	dbus_message_unref(message);
}
Exemplo n.º 7
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)" : "");
}
Exemplo n.º 8
0
static void scan_results_reply(DBusPendingCall *call, void *user_data)
{
	struct supplicant_task *task = user_data;
	DBusMessage *reply;
	DBusError error;
	char **results;
	int i, num_results;

	_DBG_SUPPLICANT("task %p", task);

	reply = dbus_pending_call_steal_reply(call);
	if (reply == NULL)
		goto noscan;

	if (dbus_message_get_type(reply) == DBUS_MESSAGE_TYPE_ERROR)
		goto done;

	dbus_error_init(&error);

	if (dbus_message_get_args(reply, &error,
				DBUS_TYPE_ARRAY, DBUS_TYPE_OBJECT_PATH,
						&results, &num_results,
						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 scan result");
		goto done;
	}

	if (num_results == 0)
		goto done;

	task->scangen++;

	for (i = 0; i < num_results; i++) {
		char *path = g_strdup(results[i]);
		if (path == NULL)
			continue;

		task->scan_results = g_slist_append(task->scan_results, path);
	}

	g_strfreev(results);

	dbus_message_unref(reply);

	get_properties(task);

	return;

done:
	dbus_message_unref(reply);

noscan:
	task->result_call = NULL;

	if (task->scanning == TRUE) {
		connman_device_set_scanning(task->device, FALSE);
		task->scanning = FALSE;
	}
}
Exemplo n.º 9
0
static void stop_autoscan(struct connman_device *device)
{
	reset_autoscan(device);

	connman_device_set_scanning(device, FALSE);
}
Exemplo n.º 10
0
static void adapter_properties_reply(DBusPendingCall *call, void *user_data)
{
	char *path = user_data;
	struct connman_device *device;
	DBusMessage *reply;
	DBusMessageIter networks;
	const char *address = NULL, *name = NULL;
	dbus_bool_t powered = FALSE, scanning = FALSE;
	struct ether_addr addr;
	char ident[13];

	DBG("path %s", path);

	reply = dbus_pending_call_steal_reply(call);

	if (path == NULL)
		goto done;

	extract_properties(reply, NULL, &address, &name, NULL,
					&powered, &scanning, NULL, &networks);

	if (address == NULL)
		goto done;

	if (g_strcmp0(address, "00:00:00:00:00:00") == 0)
		goto done;

	device = g_hash_table_lookup(bluetooth_devices, path);
	if (device != NULL)
		goto update;

	ether_aton_r(address, &addr);

	snprintf(ident, 13, "%02x%02x%02x%02x%02x%02x",
						addr.ether_addr_octet[0],
						addr.ether_addr_octet[1],
						addr.ether_addr_octet[2],
						addr.ether_addr_octet[3],
						addr.ether_addr_octet[4],
						addr.ether_addr_octet[5]);

	device = connman_device_create("bluetooth_legacy",
			CONNMAN_DEVICE_TYPE_BLUETOOTH);
	if (device == NULL)
		goto done;

	g_hash_table_insert(bluetooth_devices, g_strdup(path), device);

	connman_device_set_ident(device, ident);

	connman_device_set_string(device, "Path", path);

	if (connman_device_register(device) < 0) {
		connman_device_unref(device);
		g_hash_table_remove(bluetooth_devices, path);
		goto done;
	}

update:
	connman_device_set_string(device, "Address", address);
	connman_device_set_string(device, "Name", name);
	connman_device_set_string(device, "Path", path);

	connman_device_set_powered(device, powered);
	connman_device_set_scanning(device, scanning);

	if (powered == FALSE) {
		remove_device_networks(device);
		add_pending_networks(path, &networks);
	} else
		check_networks(&networks);

done:
	dbus_message_unref(reply);

	dbus_pending_call_unref(call);
}