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

📄 dbus-hci.c

📁 Linux的蓝牙操作工具。配合bluez-lib使用
💻 C
📖 第 1 页 / 共 4 页
字号:
		/* If there is a pending reply for discovery cancel */		if (adapter->discovery_cancel) {			DBusMessage *reply;			reply = dbus_message_new_method_return(adapter->discovery_cancel);			send_message_and_unref(connection, reply);			dbus_message_unref(adapter->discovery_cancel);			adapter->discovery_cancel = NULL;		}		/* reset the discover type for standard inquiry only */		adapter->discov_type &= ~STD_INQUIRY;	}done:	/* Proceed with any queued up audits */	process_audits_list(path);}void hcid_dbus_periodic_inquiry_start(bdaddr_t *local, uint8_t status){	struct adapter *adapter;	char path[MAX_PATH_LENGTH], local_addr[18];	int id;	/* Don't send the signal if the cmd failed */	if (status)		return;	ba2str(local, local_addr);	id = hci_devid(local_addr);	if (id < 0) {		error("No matching device id for %s", local_addr);		return;	}	snprintf(path, sizeof(path), "%s/hci%d", BASE_PATH, id);	if (dbus_connection_get_object_user_data(connection, path,							(void *) &adapter)) {		adapter->pdiscov_active = 1;		/* Disable name resolution for non D-Bus clients */		if (!adapter->pdiscov_requestor)			adapter->discov_type &= ~RESOLVE_NAME;	}	dbus_connection_emit_signal(connection, path, ADAPTER_INTERFACE,					"PeriodicDiscoveryStarted",					DBUS_TYPE_INVALID);}void hcid_dbus_periodic_inquiry_exit(bdaddr_t *local, uint8_t status){	struct adapter *adapter;	char path[MAX_PATH_LENGTH], local_addr[18];	int id;	/* Don't send the signal if the cmd failed */	if (status)		return;	ba2str(local, local_addr);	id = hci_devid(local_addr);	if (id < 0) {		error("No matching device id for %s", local_addr);		return;	}	snprintf(path, sizeof(path), "%s/hci%d", BASE_PATH, id);	if (!dbus_connection_get_object_user_data(connection, path,							(void *) &adapter)) {		error("Getting %s path data failed!", path);		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) {		name_listener_remove(connection, adapter->pdiscov_requestor,					(name_cb_t) periodic_discover_req_exit,					adapter);		g_free(adapter->pdiscov_requestor);		adapter->pdiscov_requestor = NULL;	}	 /* workaround: inquiry completed is not sent when exiting from	  * periodic inquiry */	if (adapter->discov_active) {		dbus_connection_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_signal(connection, path, ADAPTER_INTERFACE,					"PeriodicDiscoveryStopped",					DBUS_TYPE_INVALID);}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;}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], path[MAX_PATH_LENGTH];	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;	int id;	ba2str(local, local_addr);	ba2str(peer, peer_addr);	id = hci_devid(local_addr);	if (id < 0) {		error("No matching device id for %s", local_addr);		return;	}	snprintf(path, sizeof(path), "%s/hci%d", BASE_PATH, id);	if (!dbus_connection_get_object_user_data(connection, path,							(void *) &adapter)) {		error("Getting %s path data failed!", path);		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);		}	}	/* send the device found signal */	dbus_connection_emit_signal(connection, path, ADAPTER_INTERFACE,					"RemoteDeviceFound",					DBUS_TYPE_STRING, &paddr,					DBUS_TYPE_UINT32, &class,					DBUS_TYPE_INT16, &tmp_rssi,					DBUS_TYPE_INVALID);	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;		}	}	if (name) {		dbus_connection_emit_signal(connection, path,						ADAPTER_INTERFACE,						"RemoteNameUpdated",						DBUS_TYPE_STRING, &paddr,						DBUS_TYPE_STRING, &name,						DBUS_TYPE_INVALID);		g_free(name);		if (name_type != 0x08)			name_status = NAME_SENT;	}	/* 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 local_addr[18], peer_addr[18];	const char *paddr = peer_addr;	uint32_t old_class = 0;	int id;	read_remote_class(local, peer, &old_class);	if (old_class == class)		return;	ba2str(local, local_addr);	ba2str(peer, peer_addr);	id = hci_devid(local_addr);	if (id < 0) {		error("No matching device id for %s", local_addr);		return;	}	send_adapter_signal(connection, id, "RemoteClassUpdated",				DBUS_TYPE_STRING, &paddr,				DBUS_TYPE_UINT32, &class,				DBUS_TYPE_INVALID);}void hcid_dbus_remote_name(bdaddr_t *local, bdaddr_t *peer, uint8_t status,				char *name){	struct adapter *adapter;	char path[MAX_PATH_LENGTH], local_addr[18], peer_addr[18];	const char *paddr = peer_addr;	int id;	ba2str(local, local_addr);	ba2str(peer, peer_addr);	id = hci_devid(local_addr);	if (id < 0) {		error("No matching device id for %s", local_addr);		return;	}	snprintf(path, sizeof(path), "%s/hci%d", BASE_PATH, id);	if (!dbus_connection_get_object_user_data(connection, path,							(void *) &adapter)) {		error("Getting %s path data failed!", path);		return;	}	if (status)		dbus_connection_emit_signal(connection, path,						ADAPTER_INTERFACE,						"RemoteNameFailed",						DBUS_TYPE_STRING, &paddr,						DBUS_TYPE_INVALID);	else		dbus_connection_emit_signal(connection, path,						ADAPTER_INTERFACE,						"RemoteNameUpdated",						DBUS_TYPE_STRING, &paddr,						DBUS_TYPE_STRING, &name,						DBUS_TYPE_INVALID);	/* 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) {		name_listener_remove(connection, adapter->discov_requestor,				(name_cb_t) discover_devices_req_exit, adapter);		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);			send_message_and_unref(connection, 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;	}	if (adapter->discov_active) {		dbus_connection_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 path[MAX_PATH_LENGTH], local_addr[18], peer_addr[18];	const char *paddr = peer_addr;	struct adapter *adapter;	int id;	ba2str(local, local_addr);	ba2str(peer, peer_addr);	id = hci_devid(local_addr);	if (id < 0) {		error("No matching device id for %s", local_addr);		return;	}	snprintf(path, sizeof(path), "%s/hci%d", BASE_PATH, id);	if (!dbus_connection_get_object_user_data(connection, path,							(void *) &adapter)) {		error("Getting %s path data failed!", path);		return;	}	if (status) {		GSList *l;		cancel_passkey_agent_requests(adapter->passkey_agents, path,						peer);		release_passkey_agents(adapter, peer);		l = g_slist_find_custom(adapter->pin_reqs, peer, pin_req_cmp);		if (l) {			struct pending_pin_req *p = l->data;			adapter->pin_reqs = g_slist_remove(adapter->pin_reqs, p);			g_free(p);		}		if (adapter->bonding)			adapter->bonding->hci_status = status;	} else {		/* Send the remote device connected signal */		dbus_connection_emit_signal(connection, path,						ADAPTER_INTERFACE,						"RemoteDeviceConnected",						DBUS_TYPE_STRING, &paddr,						DBUS_TYPE_INVALID);		/* 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 path[MAX_PATH_LENGTH], local_addr[18], peer_addr[18];	const char *paddr = peer_addr;	struct adapter *adapter;	struct active_conn_info *dev;	GSList *l;	int id;	if (status) {		error("Disconnection failed: 0x%02x", status);		return;	}	ba2str(local, local_addr);	id = hci_devid(local_addr);	if (id < 0) {		error("No matching device id for %s", local_addr);		return;	}	snprintf(path, sizeof(path), "%s/hci%d", BASE_PATH, id);	if (!dbus_connection_get_object_user_data(connection, path,							(void *) &adapter)) {		error("Getting %s path data failed!", path);		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);	/* clean pending HCI cmds */	hci_req_queue_remove(adapter->dev_id, &dev->bdaddr);	/* Cancel D-Bus/non D-Bus requests */	cancel_passkey_agent_requests(adapter->passkey_agents, path,					&dev->bdaddr);	release_passkey_agents(adapter, &dev->bdaddr);	l = g_slist_find_custom(adapter->pin_reqs, &dev->bdaddr, pin_req_cmp);	if (l) {		struct pending_pin_req *p = l->data;		adapter->pin_reqs = g_slist_remove(adapter->pin_reqs, p);		g_free(p);	}	/* 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 */			error_authentication_canceled(connection,							adapter->bonding->rq);		} else {			reply = new_authentication_return(adapter->bonding->rq,							HCI_AUTHENTICATION_FAILURE);			send_message_and_unref(connection, reply);		}		name_listener_remove(connection,					dbus_message_get_sender(adapter->bonding->rq),					(name_cb_t) create_bond_req_exit,					adapter);		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;	}	/* Check if there is a pending RemoteDeviceDisconnect request */	if (adapter->pending_dc) {		reply = dbus_message_new_method_return(adapter->pending_dc->msg);		if (!reply)			error("Failed to allocate disconnect reply");		else			send_message_and_unref(adapter->pending_dc->conn, reply);		g_source_remove(adapter->pending_dc->timeout_id);		dc_pending_timeout_cleanup(adapter);	}	/* Send the remote device disconnected signal */	dbus_connection_emit_signal(connection, path, ADAPTER_INTERFACE,					"RemoteDeviceDisconnected",					DBUS_TYPE_STRING, &paddr,					DBUS_TYPE_INVALID);	adapter->active_conn = g_slist_remove(adapter->active_conn, dev);	g_free(dev);}int set_limited_discoverable(int dd, const uint8_t *cls, gboolean limited){	uint32_t dev_class;	int err;	int num = (limited ? 2 : 1);	uint8_t lap[] = { 0x33, 0x8b, 0x9e, 0x00, 0x8b, 0x9e };	/*	 * 1: giac	 * 2: giac + liac	 */	if (hci_write_current_iac_lap(dd, num, lap, 1000) < 0) {		err = errno;		error("Can't write current IAC LAP: %s(%d)",				strerror(err), err);		return -err;	}	if (limited) {		if (cls[1] & 0x20)			return 0; /* Already limited */		dev_class = (cls[2] << 16) | ((cls[1] | 0x20) << 8) | cls[0];	} else {		if (!(cls[1] & 0x20))			return 0; /* Already clear */		dev_class = (cls[2] << 16) | ((cls[1] & 0xdf) << 8) | cls[0];	}	if (hci_write_class_of_dev(dd, dev_class, 1000) < 0) {		err = errno;		error("Can't write class of device: %s (%d)",							strerror(err), err);		return -err;	}	return 0;

⌨️ 快捷键说明

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