⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dbus-hci.c

📁 BlueZ源码
💻 C
📖 第 1 页 / 共 3 页
字号:
	struct btd_device *device;	struct bonding_request_info *bonding;	struct pending_auth_info *auth;	debug("hcid_dbus_bonding_process_complete: status=%02x", status);	ba2str(peer, peer_addr);	adapter = manager_find_adapter(local);	if (!adapter) {		error("Unable to find matching adapter");		return;	}	bonding = adapter_get_bonding_info(adapter);	if (bonding && bacmp(&bonding->bdaddr, peer))		bonding = NULL;	if (status == 0) {		device = adapter_get_device(connection, adapter, peer_addr);		if (!device) {			/* This should really only happen if we run out of			 * memory */			error("Unable to get device object!");			status = HCI_REJECTED_LIMITED_RESOURCES;		}	}	if (status && bonding)		bonding->hci_status = status;	auth = adapter_find_auth_request(adapter, peer);	if (!auth) {		/* This means that there was no pending PIN or SSP token request		 * from the controller, i.e. this is not a new pairing */		debug("hcid_dbus_bonding_process_complete: no pending auth request");		goto proceed;	}	if (auth->agent)		agent_cancel(auth->agent);	adapter_remove_auth_request(adapter, peer);	/* If this is a new pairing send the appropriate signal for it	 * and proceed with service discovery */	if (status == 0) {		device_set_paired(connection, device, bonding);		if (bonding)			adapter_free_bonding_request(adapter);		return;	}proceed:	if (!bonding)		return; /* skip: no bonding req pending */	if (bonding->cancel)		reply = new_authentication_return(bonding->msg,					HCI_OE_USER_ENDED_CONNECTION);	else		reply = new_authentication_return(bonding->msg, status);	g_dbus_send_message(connection, reply);	adapter_free_bonding_request(adapter);}void hcid_dbus_inquiry_start(bdaddr_t *local){	struct btd_adapter *adapter;	int state;	adapter = manager_find_adapter(local);	if (!adapter) {		error("Unable to find matching adapter");		return;	}	state = adapter_get_state(adapter);	state |= STD_INQUIRY;	adapter_set_state(adapter, state);	/*	 * Cancel pending remote name request and clean the device list	 * when inquiry is supported in periodic inquiry idle state.	 */	if (adapter_get_state(adapter) & PERIODIC_INQUIRY)		pending_remote_name_cancel(adapter);	/* Disable name resolution for non D-Bus clients */	if (!adapter_has_discov_sessions(adapter)) {		state = adapter_get_state(adapter);		state &= ~RESOLVE_NAME;		adapter_set_state(adapter, state);	}}static int found_device_req_name(struct btd_adapter *adapter){	struct hci_request rq;	evt_cmd_status rp;	remote_name_req_cp cp;	struct remote_dev_info *dev, match;	int dd, req_sent = 0;	uint16_t dev_id = adapter_get_dev_id(adapter);	memset(&match, 0, sizeof(struct remote_dev_info));	bacpy(&match.bdaddr, BDADDR_ANY);	match.name_status = NAME_REQUIRED;	dev = adapter_search_found_devices(adapter, &match);	if (!dev)		return -ENODATA;	dd = hci_open_dev(dev_id);	if (dd < 0)		return -errno;	memset(&rq, 0, sizeof(rq));	rq.ogf    = OGF_LINK_CTL;	rq.ocf    = OCF_REMOTE_NAME_REQ;	rq.cparam = &cp;	rq.clen   = REMOTE_NAME_REQ_CP_SIZE;	rq.rparam = &rp;	rq.rlen   = EVT_CMD_STATUS_SIZE;	rq.event  = EVT_CMD_STATUS;	/* send at least one request or return failed if the list is empty */	do {		/* flag to indicate the current remote name requested */		dev->name_status = NAME_REQUESTED;		memset(&rp, 0, sizeof(rp));		memset(&cp, 0, sizeof(cp));		bacpy(&cp.bdaddr, &dev->bdaddr);		cp.pscan_rep_mode = 0x02;		if (hci_send_req(dd, &rq, HCI_REQ_TIMEOUT) < 0)			error("Unable to send the HCI remote name request: %s (%d)",						strerror(errno), errno);		if (!rp.status) {			req_sent = 1;			break;		}		error("Remote name request failed with status 0x%02x",								rp.status);		/* if failed, request the next element */		/* remove the element from the list */		adapter_remove_found_device(adapter, &dev->bdaddr);		/* get the next element */		dev = adapter_search_found_devices(adapter, &match);	} while (dev);	hci_close_dev(dd);	if (!req_sent)		return -ENODATA;	return 0;}void hcid_dbus_inquiry_complete(bdaddr_t *local){	struct btd_adapter *adapter;	const gchar *path;	int state;	adapter = manager_find_adapter(local);	if (!adapter) {		error("Unable to find matching adapter");		return;	}	path = adapter_get_path(adapter);	/* Out of range verification */	if ((adapter_get_state(adapter) & PERIODIC_INQUIRY) &&				!(adapter_get_state(adapter) & STD_INQUIRY))		adapter_update_oor_devices(adapter);	/*	 * The following scenarios can happen:	 * 1. standard inquiry: always send discovery completed signal	 * 2. standard inquiry + name resolving: send discovery completed	 *    after name resolving	 * 3. periodic inquiry: skip discovery completed signal	 * 4. periodic inquiry + standard inquiry: always send discovery	 *    completed signal	 *	 * Keep in mind that non D-Bus requests can arrive.	 */	if (found_device_req_name(adapter) == 0)		return;	/* reset the discover type to be able to handle D-Bus and non D-Bus	 * requests */	state = adapter_get_state(adapter);	state &= ~STD_INQUIRY;	state &= ~PERIODIC_INQUIRY;	adapter_set_state(adapter, state);}void hcid_dbus_periodic_inquiry_start(bdaddr_t *local, uint8_t status){	struct btd_adapter *adapter;	int state;	/* Don't send the signal if the cmd failed */	if (status)		return;	adapter = manager_find_adapter(local);	if (!adapter) {		error("No matching adapter found");		return;	}	state = adapter_get_state(adapter);	state |= PERIODIC_INQUIRY;	adapter_set_state(adapter, state);}void hcid_dbus_periodic_inquiry_exit(bdaddr_t *local, uint8_t status){	struct btd_adapter *adapter;	int state;	/* Don't send the signal if the cmd failed */	if (status)		return;	adapter = manager_find_adapter(local);	if (!adapter) {		error("No matching adapter found");		return;	}	/* reset the discover type to be able to handle D-Bus and non D-Bus	 * requests */	state = adapter_get_state(adapter);	state &= ~PERIODIC_INQUIRY;	adapter_set_state(adapter, state);}static char *extract_eir_name(uint8_t *data, uint8_t *type){	if (!data || !type)		return NULL;	if (data[0] == 0)		return NULL;	*type = data[1];	switch (*type) {	case 0x08:	case 0x09:		return strndup((char *) (data + 2), data[0] - 1);	}	return NULL;}static void append_dict_valist(DBusMessageIter *iter,					const char *first_key,					va_list var_args){	DBusMessageIter dict;	const char *key;	int type;	void *val;	dbus_message_iter_open_container(iter, DBUS_TYPE_ARRAY,			DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING			DBUS_TYPE_STRING_AS_STRING DBUS_TYPE_VARIANT_AS_STRING			DBUS_DICT_ENTRY_END_CHAR_AS_STRING, &dict);	key = first_key;	while (key) {		type = va_arg(var_args, int);		val = va_arg(var_args, void *);		dict_append_entry(&dict, key, type, val);		key = va_arg(var_args, char *);	}	dbus_message_iter_close_container(iter, &dict);}static void emit_device_found(const char *path, const char *address,				const char *first_key, ...){	DBusMessage *signal;	DBusMessageIter iter;	va_list var_args;	signal = dbus_message_new_signal(path, ADAPTER_INTERFACE,					"DeviceFound");	if (!signal) {		error("Unable to allocate new %s.DeviceFound signal",				ADAPTER_INTERFACE);		return;	}	dbus_message_iter_init_append(signal, &iter);	dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &address);	va_start(var_args, first_key);	append_dict_valist(&iter, first_key, var_args);	va_end(var_args);	g_dbus_send_message(connection, signal);}void hcid_dbus_inquiry_result(bdaddr_t *local, bdaddr_t *peer, uint32_t class,				int8_t rssi, uint8_t *data){	char filename[PATH_MAX + 1];	struct btd_adapter *adapter;	char local_addr[18], peer_addr[18], *alias, *name, *tmp_name;	const char *real_alias;	const char *path, *icon, *paddr = peer_addr;	struct remote_dev_info *dev, match;	dbus_int16_t tmp_rssi = rssi;	uint8_t name_type = 0x00;	name_status_t name_status;	int state;	ba2str(local, local_addr);	ba2str(peer, peer_addr);	adapter = manager_find_adapter(local);	if (!adapter) {		error("No matching adapter found");		return;	}	write_remote_class(local, peer, class);	if (data)		write_remote_eir(local, peer, data);	/*	 * workaround to identify situation when the daemon started and	 * a standard inquiry or periodic inquiry was already running	 */	if (!(adapter_get_state(adapter) & STD_INQUIRY) &&			!(adapter_get_state(adapter) & PERIODIC_INQUIRY)) {		state = adapter_get_state(adapter);		state |= PERIODIC_INQUIRY;		adapter_set_state(adapter, state);	}	/* Out of range list update */	if (adapter_get_state(adapter) & PERIODIC_INQUIRY)		adapter_remove_oor_device(adapter, peer_addr);	memset(&match, 0, sizeof(struct remote_dev_info));	bacpy(&match.bdaddr, peer);	match.name_status = NAME_SENT;	/* if found: don't send the name again */	dev = adapter_search_found_devices(adapter, &match);	if (dev)		return;	/* the inquiry result can be triggered by NON D-Bus client */	if (adapter_get_state(adapter) & RESOLVE_NAME)		name_status = NAME_REQUIRED;	else		name_status = NAME_NOT_REQUIRED;	create_name(filename, PATH_MAX, STORAGEDIR, local_addr, "aliases");	alias = textfile_get(filename, peer_addr);	create_name(filename, PATH_MAX, STORAGEDIR, local_addr, "names");	name = textfile_get(filename, peer_addr);	if (!alias) {		real_alias = NULL;		if (!name) {			alias = g_strdup(peer_addr);			g_strdelimit(alias, ":", '-');		} else			alias = g_strdup(name);	} else		real_alias = alias;	tmp_name = extract_eir_name(data, &name_type);	if (tmp_name) {		if (name_type == 0x09) {			write_device_name(local, peer, tmp_name);			name_status = NAME_NOT_REQUIRED;			if (name)				g_free(name);			name = tmp_name;		} else {			if (name)				free(tmp_name);			else				name = tmp_name;		}	}	path = adapter_get_path(adapter);	icon = class_to_icon(class);	emit_device_found(path, paddr,				"Address", DBUS_TYPE_STRING, &paddr,				"Class", DBUS_TYPE_UINT32, &class,				"Icon", DBUS_TYPE_STRING, &icon,				"RSSI", DBUS_TYPE_INT16, &tmp_rssi,				"Name", DBUS_TYPE_STRING, &name,				"Alias", DBUS_TYPE_STRING, &alias, NULL);	if (name && name_type != 0x08)		name_status = NAME_SENT;	/* add in the list to track name sent/pending */	adapter_add_found_device(adapter, peer, rssi, class, real_alias,					name_status);	g_free(name);	g_free(alias);}void hcid_dbus_remote_class(bdaddr_t *local, bdaddr_t *peer, uint32_t class){	char peer_addr[18];	const char *paddr = peer_addr;	uint32_t old_class = 0;	struct btd_adapter *adapter;	struct btd_device *device;	const gchar *dev_path;	read_remote_class(local, peer, &old_class);	if (old_class == class)		return;	adapter = manager_find_adapter(local);	if (!adapter) {		error("No matching adapter found");		return;	}	ba2str(peer, peer_addr);	device = adapter_find_device(adapter, paddr);	if (!device)		return;	dev_path = device_get_path(device);	emit_property_changed(connection, dev_path, DEVICE_INTERFACE, "Class",				DBUS_TYPE_UINT32, &class);}void hcid_dbus_remote_name(bdaddr_t *local, bdaddr_t *peer, uint8_t status,				char *name){	struct btd_adapter *adapter;	char srcaddr[18], dstaddr[18];	int state;	struct btd_device *device;	struct remote_dev_info match, *dev_info;	adapter = manager_find_adapter(local);	if (!adapter) {		error("No matching adapter found");		return;	}	ba2str(local, srcaddr);	ba2str(peer, dstaddr);	if (status != 0)		goto proceed;	bacpy(&match.bdaddr, peer);	match.name_status = NAME_ANY;	dev_info = adapter_search_found_devices(adapter, &match);	if (dev_info) {		const char *adapter_path = adapter_get_path(adapter);		const char *icon = class_to_icon(dev_info->class);		const char *alias, *paddr = dstaddr;		dbus_int16_t rssi = dev_info->rssi;		if (dev_info->alias)			alias = dev_info->alias;		else			alias = name;		emit_device_found(adapter_path, dstaddr,				"Address", DBUS_TYPE_STRING, &paddr,				"Class", DBUS_TYPE_UINT32, &dev_info->class,				"Icon", DBUS_TYPE_STRING, &icon,				"RSSI", DBUS_TYPE_INT16, &rssi,				"Name", DBUS_TYPE_STRING, &name,				"Alias", DBUS_TYPE_STRING, &alias,				NULL);	}	device = adapter_find_device(adapter, dstaddr);	if (device) {		char alias[248];		const char *dev_path = device_get_path(device);		emit_property_changed(connection, dev_path,				DEVICE_INTERFACE, "Name",				DBUS_TYPE_STRING, &name);		if (read_device_alias(srcaddr, dstaddr,					alias, sizeof(alias)) < 1)			emit_property_changed(connection, dev_path,					DEVICE_INTERFACE, "Alias",					DBUS_TYPE_STRING, &name);	}proceed:	/* remove from remote name request list */	adapter_remove_found_device(adapter, peer);	/* check if there is more devices to request names */	if (found_device_req_name(adapter) == 0)		return;	state = adapter_get_state(adapter);	state &= ~PERIODIC_INQUIRY;	state &= ~STD_INQUIRY;	adapter_set_state(adapter, state);}void hcid_dbus_link_key_notify(bdaddr_t *local, bdaddr_t *peer){	char peer_addr[18];	struct btd_device *device;	struct btd_adapter *adapter;	struct bonding_request_info *bonding;	adapter = manager_find_adapter(local);	if (!adapter) {		error("No matching adapter found");		return;	}	ba2str(peer, peer_addr);	device = adapter_find_device(adapter, peer_addr);	if (!device) {		error("link_key_notify: device %s was removed!", peer_addr);		return;	}	bonding = adapter_get_bonding_info(adapter);	if (!device_get_connected(device))		device_set_secmode3_conn(device, TRUE);	else if (!bonding)		hcid_dbus_bonding_process_complete(local, peer, 0);}void hcid_dbus_conn_complete(bdaddr_t *local, uint8_t status, uint16_t handle,				bdaddr_t *peer)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -