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

📄 dbus-hci.c

📁 这是Linux环境下的蓝牙源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
	if (dev_id < 0)		return dev_id;	dd = hci_open_dev(dev_id);	if (dd < 0)		return dd;	memset(&req, 0, sizeof(req));	bacpy(&req.bdaddr, remote);	err = ioctl(dd, HCIGETAUTHINFO, (unsigned long) &req);	if (err < 0) {		debug("HCIGETAUTHINFO failed: %s (%d)",					strerror(errno), errno);		hci_close_dev(dd);		return err;	}	hci_close_dev(dd);	if (auth)		*auth = req.type;	return 0;}int hcid_dbus_user_confirm(bdaddr_t *sba, bdaddr_t *dba, uint32_t passkey){	struct adapter *adapter;	struct btd_device *device;	struct agent *agent;	char addr[18];	uint8_t type;	struct pending_auth_info *auth;	uint16_t dev_id;	adapter = manager_find_adapter(sba);	if (!adapter) {		error("No matching adapter found");		return -1;	}	dev_id = adapter_get_dev_id(adapter);	if (get_auth_requirements(sba, dba, &type) < 0) {		int dd;		dd = hci_open_dev(dev_id);		if (dd < 0) {			error("Unable to open hci%d", dev_id);			return -1;		}		hci_send_cmd(dd, OGF_LINK_CTL,					OCF_USER_CONFIRM_NEG_REPLY, 6, dba);		hci_close_dev(dd);		return 0;	}	ba2str(dba, addr);	device = adapter_get_device(connection, adapter, addr);	if (!device) {		error("Device creation failed");		return -1;	}	/* If no MITM protection required, auto-accept */	if (!(device_get_auth(device) & 0x01) && !(type & 0x01)) {		int dd;		dd = hci_open_dev(dev_id);		if (dd < 0) {			error("Unable to open hci%d", dev_id);			return -1;		}		hci_send_cmd(dd, OGF_LINK_CTL,					OCF_USER_CONFIRM_REPLY, 6, dba);		hci_close_dev(dd);		return 0;	}	agent = device_get_agent(device);	if (!agent)		agent = adapter->agent;	if (!agent) {		error("No agent available for user confirm request");		return -1;	}	if (agent_request_confirmation(agent, device, passkey,						confirm_cb, device) < 0) {		error("Requesting passkey failed");		return -1;	}	auth = adapter_new_auth_request(adapter, dba, AUTH_TYPE_CONFIRM);	auth->agent = agent;	return 0;}int hcid_dbus_user_passkey(bdaddr_t *sba, bdaddr_t *dba){	struct adapter *adapter;	struct btd_device *device;	struct agent *agent = NULL;	char addr[18];	struct pending_auth_info *auth;	adapter = manager_find_adapter(sba);	if (!adapter) {		error("No matching adapter found");		return -1;	}	ba2str(dba, addr);	device = adapter_get_device(connection, adapter, addr);	if (device)		agent = device_get_agent(device);	if (!agent)		agent = adapter->agent;	if (!agent) {		error("No agent available for user confirm request");		return -1;	}	if (agent_request_passkey(agent, device, passkey_cb, device) < 0) {		error("Requesting passkey failed");		return -1;	}	auth = adapter_new_auth_request(adapter, dba, AUTH_TYPE_PASSKEY);	auth->agent = agent;	return 0;}int hcid_dbus_user_notify(bdaddr_t *sba, bdaddr_t *dba, uint32_t passkey){	struct adapter *adapter;	struct btd_device *device;	struct agent *agent = NULL;	char addr[18];	struct pending_auth_info *auth;	adapter = manager_find_adapter(sba);	if (!adapter) {		error("No matching adapter found");		return -1;	}	ba2str(dba, addr);	device = adapter_get_device(connection, adapter, addr);	if (device)		agent = device_get_agent(device);	if (!agent)		agent = adapter->agent;	if (!agent) {		error("No agent available for user confirm request");		return -1;	}	if (agent_display_passkey(agent, device, passkey) < 0) {		error("Displaying passkey failed");		return -1;	}	auth = adapter_new_auth_request(adapter, dba, AUTH_TYPE_NOTIFY);	auth->agent = agent;	return 0;}void hcid_dbus_bonding_process_complete(bdaddr_t *local, bdaddr_t *peer,					uint8_t status){	struct adapter *adapter;	char peer_addr[18];	const char *paddr = peer_addr;	DBusMessage *reply;	struct btd_device *device;	struct bonding_request_info *bonding;	gboolean paired = TRUE;	struct pending_auth_info *auth;	const gchar *dev_path;	const gchar *path;	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;	}	if (status) {		if (adapter->bonding)			adapter->bonding->hci_status = status;	}	auth = adapter_find_auth_request(adapter, peer);	if (!auth) {		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 (status)		goto proceed;	device = adapter_get_device(connection, adapter, paddr);	if (device) {		debug("hcid_dbus_bonding_process_complete: removing temporary flag");		device_set_temporary(device, FALSE);		dev_path = device_get_path(device);		path = adapter_get_path(adapter);		g_dbus_emit_signal(connection, path,				ADAPTER_INTERFACE, "DeviceCreated",				DBUS_TYPE_OBJECT_PATH, &dev_path,				DBUS_TYPE_INVALID);		dbus_connection_emit_property_changed(connection, dev_path,					DEVICE_INTERFACE, "Paired",					DBUS_TYPE_BOOLEAN, &paired);	}proceed:	bonding = adapter->bonding;	if (!bonding || bacmp(&bonding->bdaddr, peer))		return; /* skip: no bonding req pending */	if (bonding->cancel) {		/* reply authentication canceled */		reply = new_authentication_return(bonding->msg,				HCI_OE_USER_ENDED_CONNECTION);		g_dbus_send_message(connection, reply);		goto cleanup;	}	/* reply authentication success or an error */	if (dbus_message_is_method_call(bonding->msg, ADAPTER_INTERFACE,					"CreateBonding")) {		reply = new_authentication_return(bonding->msg, status);		dbus_connection_send(connection, reply, NULL);		dbus_message_unref(reply);	} else if ((device = adapter_find_device(adapter, paddr))) {		if (status) {			reply = new_authentication_return(bonding->msg, status);			dbus_connection_send(connection, reply, NULL);			dbus_message_unref(reply);		} else {			device_set_temporary(device, FALSE);			device_browse(device, bonding->conn,					bonding->msg, NULL);		}	}cleanup:	g_dbus_remove_watch(connection, 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;}void hcid_dbus_inquiry_start(bdaddr_t *local){	struct adapter *adapter;	const gchar *path;	adapter = manager_find_adapter(local);	if (!adapter) {		error("Unable to find matching adapter");		return;	}	adapter->discov_active = 1;	/*	 * Cancel pending remote name request and clean the device list	 * when inquiry is supported in periodic inquiry idle state.	 */	if (adapter->pdiscov_active)		pending_remote_name_cancel(adapter);	/* Disable name resolution for non D-Bus clients */	if (!adapter->discov_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->discov_active);	g_dbus_emit_signal(connection, path,			ADAPTER_INTERFACE, "DiscoveryStarted",			DBUS_TYPE_INVALID);}int found_device_req_name(struct adapter *adapter){	struct hci_request rq;	evt_cmd_status rp;	remote_name_req_cp cp;	struct remote_dev_info match;	GSList *l;	int dd, req_sent = 0;	uint16_t dev_id = adapter_get_dev_id(adapter);	/* get the next remote address */	if (!adapter->found_devices)		return -ENODATA;	memset(&match, 0, sizeof(struct remote_dev_info));	bacpy(&match.bdaddr, BDADDR_ANY);	match.name_status = NAME_REQUIRED;	l = g_slist_find_custom(adapter->found_devices, &match,					(GCompareFunc) found_device_cmp);	if (!l)		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 {		struct remote_dev_info *dev = l->data;		 /* 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, 500) < 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->found_devices = g_slist_remove(adapter->found_devices, dev);		g_free(dev);		/* get the next element */		l = g_slist_find_custom(adapter->found_devices, &match,					(GCompareFunc) found_device_cmp);	} while (l);	hci_close_dev(dd);	if (!req_sent)		return -ENODATA;	return 0;}static void send_out_of_range(const char *path, GSList *l){	while (l) {		const char *peer_addr = l->data;		g_dbus_emit_signal(connection, path,				ADAPTER_INTERFACE, "DeviceDisappeared",				DBUS_TYPE_STRING, &peer_addr,				DBUS_TYPE_INVALID);		l = l->next;	}}void hcid_dbus_inquiry_complete(bdaddr_t *local){	struct adapter *adapter;	struct remote_dev_info *dev;	bdaddr_t tmp;	const gchar *path;	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->pdiscov_active && !adapter->discov_active) {		GSList *l;		send_out_of_range(path, adapter->oor_devices);		g_slist_foreach(adapter->oor_devices, (GFunc) free, NULL);		g_slist_free(adapter->oor_devices);		adapter->oor_devices = NULL;		l = adapter->found_devices;		while (l) {			dev = l->data;			baswap(&tmp, &dev->bdaddr);			adapter->oor_devices = g_slist_append(adapter->oor_devices,								batostr(&tmp));			l = l->next;		}	}	adapter->pinq_idle = 1;	/*	 * Enable resolution again: standard inquiry can be	 * received in the periodic inquiry idle state.	 */	if (adapter->pdiscov_requestor && adapter->pdiscov_resolve_names)		adapter->discov_type |= RESOLVE_NAME;	/*	 * 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))		return;		/* skip - there is name to resolve */	if (adapter->discov_active) {		g_dbus_emit_signal(connection, path,				ADAPTER_INTERFACE, "DiscoveryCompleted",				DBUS_TYPE_INVALID);		adapter->discov_active = 0;	}	/* free discovered devices list */	g_slist_foreach(adapter->found_devices, (GFunc) g_free, NULL);	g_slist_free(adapter->found_devices);	adapter->found_devices = NULL;	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;		}		/* reset the discover type for standard inquiry only */		adapter->discov_type &= ~STD_INQUIRY;	}

⌨️ 快捷键说明

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