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

📄 dbus-hci.c

📁 这是Linux环境下的蓝牙源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
}void hcid_dbus_periodic_inquiry_start(bdaddr_t *local, uint8_t status){	struct adapter *adapter;	const gchar *path;	/* 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;	}	adapter->pdiscov_active = 1;	/* Disable name resolution for non D-Bus clients */	if (!adapter->pdiscov_requestor)		adapter->discov_type &= ~RESOLVE_NAME;	path = adapter_get_path(adapter);	dbus_connection_emit_property_changed(connection, path,				ADAPTER_INTERFACE, "PeriodicDiscovery",				DBUS_TYPE_BOOLEAN, &adapter->pdiscov_active);}void hcid_dbus_periodic_inquiry_exit(bdaddr_t *local, uint8_t status){	struct adapter *adapter;	const gchar *path;	/* 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 */	adapter->pdiscov_active = 0;	adapter->discov_type &= ~(PERIODIC_INQUIRY | RESOLVE_NAME);	/* free discovered devices list */	g_slist_foreach(adapter->found_devices, (GFunc) g_free, NULL);	g_slist_free(adapter->found_devices);	adapter->found_devices = NULL;	/* free out of range devices list */	g_slist_foreach(adapter->oor_devices, (GFunc) free, NULL);	g_slist_free(adapter->oor_devices);	adapter->oor_devices = NULL;	if (adapter->pdiscov_requestor) {		g_dbus_remove_watch(connection, adapter->pdiscov_listener);		adapter->pdiscov_listener = 0;		g_free(adapter->pdiscov_requestor);		adapter->pdiscov_requestor = NULL;	}	path = adapter_get_path(adapter);	/* workaround: inquiry completed is not sent when exiting from	  * periodic inquiry */	if (adapter->discov_active) {		g_dbus_emit_signal(connection, path,				ADAPTER_INTERFACE, "DiscoveryCompleted",				DBUS_TYPE_INVALID);		adapter->discov_active = 0;	}	/* Send discovery completed signal if there isn't name to resolve */	dbus_connection_emit_property_changed(connection, path,				ADAPTER_INTERFACE, "PeriodicDiscovery",				DBUS_TYPE_BOOLEAN, &adapter->discov_active);}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 *);		dbus_message_iter_append_dict_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);	dbus_connection_send(connection, signal, NULL);	dbus_message_unref(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 adapter *adapter;	GSList *l;	char local_addr[18], peer_addr[18], *name, *tmp_name;	const char *paddr = peer_addr;	struct remote_dev_info match;	dbus_int16_t tmp_rssi = rssi;	uint8_t name_type = 0x00;	name_status_t name_status;	const gchar *path;	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->discov_active && !adapter->pdiscov_active)		adapter->pdiscov_active = 1;	/* reset the idle flag when the inquiry complete event arrives */	if (adapter->pdiscov_active) {		adapter->pinq_idle = 0;		/* Out of range list update */		l = g_slist_find_custom(adapter->oor_devices, peer_addr,				(GCompareFunc) strcmp);		if (l) {			char *dev = l->data;			adapter->oor_devices = g_slist_remove(adapter->oor_devices,								dev);			g_free(dev);		}	}	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 */	l = g_slist_find_custom(adapter->found_devices, &match,			(GCompareFunc) found_device_cmp);	if (l)		return;	/* the inquiry result can be triggered by NON D-Bus client */	if (adapter->discov_type & RESOLVE_NAME)		name_status = NAME_REQUIRED;	else		name_status = NAME_NOT_REQUIRED;	create_name(filename, PATH_MAX, STORAGEDIR, local_addr, "names");	name = textfile_get(filename, peer_addr);	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);	if (name) {		if (name_type != 0x08)			name_status = NAME_SENT;		emit_device_found(path, paddr,				"Address", DBUS_TYPE_STRING, &paddr,				"Class", DBUS_TYPE_UINT32, &class,				"RSSI", DBUS_TYPE_INT16, &tmp_rssi,				"Name", DBUS_TYPE_STRING, &name,				NULL);		g_free(name);	} else {		emit_device_found(path, paddr,				"Address", DBUS_TYPE_STRING, &paddr,				"Class", DBUS_TYPE_UINT32, &class,				"RSSI", DBUS_TYPE_INT16, &tmp_rssi,				NULL);	}	/* add in the list to track name sent/pending */	found_device_add(&adapter->found_devices, peer, rssi, name_status);}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 adapter *adapter;	GSList *l;	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);	l = g_slist_find_custom(adapter->devices, paddr,				(GCompareFunc) device_address_cmp);	if (!l)		return;	device = l->data;	dev_path = device_get_path(device);	dbus_connection_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 adapter *adapter;	char peer_addr[18];	const char *paddr = peer_addr;	const gchar *dev_path;	const gchar *path;	adapter = manager_find_adapter(local);	if (!adapter) {		error("No matching adapter found");		return;	}	ba2str(peer, peer_addr);	if (!status) {		struct btd_device *device;		device = adapter_find_device(adapter, paddr);		if (device) {			dev_path = device_get_path(device);			dbus_connection_emit_property_changed(connection,						dev_path, DEVICE_INTERFACE,						"Name", DBUS_TYPE_STRING, &name);		}	}	/* remove from remote name request list */	found_device_remove(&adapter->found_devices, peer);	/* check if there is more devices to request names */	if (!found_device_req_name(adapter))		return; /* skip if a new request has been sent */	/* free discovered devices list */	g_slist_foreach(adapter->found_devices, (GFunc) g_free, NULL);	g_slist_free(adapter->found_devices);	adapter->found_devices = NULL;	/* The discovery completed signal must be sent only for discover	 * devices request WITH name resolving */	if (adapter->discov_requestor) {		g_dbus_remove_watch(connection, adapter->discov_listener);		adapter->discov_listener = 0;		g_free(adapter->discov_requestor);		adapter->discov_requestor = NULL;		/* If there is a pending reply for discovery cancel */		if (adapter->discovery_cancel) {			DBusMessage *reply;			reply = dbus_message_new_method_return(adapter->discovery_cancel);			dbus_connection_send(connection, reply, NULL);			dbus_message_unref(reply);			dbus_message_unref(adapter->discovery_cancel);			adapter->discovery_cancel = NULL;		}		/* Disable name resolution for non D-Bus clients */		if (!adapter->pdiscov_requestor)			adapter->discov_type &= ~RESOLVE_NAME;	}	path = adapter_get_path(adapter);	if (adapter->discov_active) {		g_dbus_emit_signal(connection, path,				ADAPTER_INTERFACE, "DiscoveryCompleted",				DBUS_TYPE_INVALID);		adapter->discov_active = 0;	}}void hcid_dbus_conn_complete(bdaddr_t *local, uint8_t status, uint16_t handle,				bdaddr_t *peer){	char peer_addr[18];	const char *paddr = peer_addr;	struct adapter *adapter;	const gchar *dev_path;	adapter = manager_find_adapter(local);	if (!adapter) {		error("No matching adapter found");		return;	}	ba2str(peer, peer_addr);	if (status) {		struct pending_auth_info *auth;		auth = adapter_find_auth_request(adapter, peer);		if (auth && auth->agent)			agent_cancel(auth->agent);		adapter_remove_auth_request(adapter, peer);		if (adapter->bonding)			adapter->bonding->hci_status = status;	} else {		struct btd_device *device;		gboolean connected = TRUE;		device = adapter_find_device(adapter, paddr);		if (device) {		  dev_path = device_get_path(device);		  dbus_connection_emit_property_changed(connection,					dev_path, DEVICE_INTERFACE,					"Connected", DBUS_TYPE_BOOLEAN,					&connected);		}		/* add in the active connetions list */		active_conn_append(&adapter->active_conn, peer, handle);	}}void hcid_dbus_disconn_complete(bdaddr_t *local, uint8_t status,				uint16_t handle, uint8_t reason){	DBusMessage *reply;	char peer_addr[18];	const char *paddr = peer_addr;	struct adapter *adapter;	struct btd_device *device;	struct active_conn_info *dev;	GSList *l;	gboolean connected = FALSE;	struct pending_auth_info *auth;	const gchar *destination;	const gchar *dev_path;	uint16_t dev_id;	if (status) {		error("Disconnection failed: 0x%02x", status);		return;	}	adapter = manager_find_adapter(local);	if (!adapter) {		error("No matching adapter found");		return;	}	l = g_slist_find_custom(adapter->active_conn, &handle,				active_conn_find_by_handle);	if (!l)		return;	dev = l->data;	ba2str(&dev->bdaddr, peer_addr);	dev_id = adapter_get_dev_id(adapter);	/* clean pending HCI cmds */	hci_req_queue_remove(dev_id, &dev->bdaddr);	/* Cancel D-Bus/non D-Bus requests */	auth = adapter_find_auth_request(adapter, &dev->bdaddr);	if (auth && auth->agent)		agent_cancel(auth->agent);	adapter_remove_auth_request(adapter, &dev->bdaddr);	/* Check if there is a pending CreateBonding request */	if (adapter->bonding && (bacmp(&adapter->bonding->bdaddr, &dev->bdaddr) == 0)) {		if (adapter->bonding->cancel) {			/* reply authentication canceled */			reply = new_authentication_return(adapter->bonding->msg,							HCI_OE_USER_ENDED_CONNECTION);			g_dbus_send_message(connection, reply);		} else {			reply = new_authentication_return(adapter->bonding->msg,							HCI_AUTHENTICATION_FAILURE);			dbus_connection_send(connection, reply, NULL);			dbus_message_unref(reply);		}		g_dbus_remove_watch(adapter->bonding->conn,					adapter->bonding->listener_id);		if (adapter->bonding->io_id)			g_source_remove(adapter->bonding->io_id);		g_io_channel_close(adapter->bonding->io);		bonding_request_free(adapter->bonding);		adapter->bonding = NULL;	}	adapter->active_conn = g_slist_remove(adapter->active_conn, dev);	g_free(dev);	device = adapter_find_device(adapter, paddr);	if (device) {		destination = device_get_address(device);		dev_path = device_get_path(device);

⌨️ 快捷键说明

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