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

📄 adapter.c

📁 BlueZ源码
💻 C
📖 第 1 页 / 共 5 页
字号:
	int dd;	uint8_t scan_enable;	uint16_t dev_id = adapter->dev_id;	adapter->discov_timeout_id = 0;	dd = hci_open_dev(dev_id);	if (dd < 0) {		error("HCI device open failed: hci%d", dev_id);		return FALSE;	}	scan_enable = adapter->scan_mode & ~SCAN_INQUIRY;	hci_send_cmd(dd, OGF_HOST_CTL, OCF_WRITE_SCAN_ENABLE,					1, &scan_enable);	hci_close_dev(dd);	return FALSE;}static void adapter_set_discov_timeout(struct btd_adapter *adapter,					guint interval){	if (adapter->discov_timeout_id) {		g_source_remove(adapter->discov_timeout_id);		adapter->discov_timeout_id = 0;	}	if (interval == 0)		return;	adapter->discov_timeout_id = g_timeout_add_seconds(interval,							discov_timeout_handler,							adapter);}static uint8_t mode2scan(uint8_t mode){	switch (mode) {	case MODE_OFF:		return SCAN_DISABLED;	case MODE_CONNECTABLE:		return SCAN_PAGE;	case MODE_DISCOVERABLE:	case MODE_LIMITED:		return (SCAN_PAGE | SCAN_INQUIRY);	default:		error("Invalid mode given to mode2scan: %u", mode);		return SCAN_PAGE;	}}static int set_mode(struct btd_adapter *adapter, uint8_t new_mode){	uint8_t scan_enable;	uint8_t current_scan = adapter->scan_mode;	int err, dd;	const char *modestr;	scan_enable = mode2scan(new_mode);	dd = hci_open_dev(adapter->dev_id);	if (dd < 0)		return -EIO;	if (!adapter->up &&			(main_opts.offmode == HCID_OFFMODE_NOSCAN ||			 (main_opts.offmode == HCID_OFFMODE_DEVDOWN &&			  scan_enable != SCAN_DISABLED))) {		/* Start HCI device */		if (ioctl(dd, HCIDEVUP, adapter->dev_id) == 0)			goto done; /* on success */		if (errno != EALREADY) {			err = -errno;			error("Can't init device hci%d: %s (%d)\n",				adapter->dev_id, strerror(errno), errno);			hci_close_dev(dd);			return err;		}	}	if (adapter->up && scan_enable == SCAN_DISABLED &&			main_opts.offmode == HCID_OFFMODE_DEVDOWN) {		if (ioctl(dd, HCIDEVDOWN, adapter->dev_id) < 0) {			err = -errno;			hci_close_dev(dd);			return err;		}		goto done;	}	if (current_scan != scan_enable) {		err = hci_send_cmd(dd, OGF_HOST_CTL, OCF_WRITE_SCAN_ENABLE,					1, &scan_enable);		if (err < 0) {			hci_close_dev(dd);			return err;		}	} else {		/* discoverable or limited */		if ((scan_enable & SCAN_INQUIRY) && (new_mode != adapter->mode)) {			adapter_remove_discov_timeout(adapter);			if (adapter->discov_timeout)				adapter_set_discov_timeout(adapter,						adapter->discov_timeout);		}	}done:	modestr = mode2str(new_mode);	write_device_mode(&adapter->bdaddr, modestr);	hci_close_dev(dd);	adapter->mode = new_mode;	return 0;}static DBusMessage *set_powered(DBusConnection *conn, DBusMessage *msg,				gboolean powered, void *data){	struct btd_adapter *adapter = data;	uint8_t mode;	int err;	mode = powered ? get_mode(&adapter->bdaddr, "on") : MODE_OFF;	if (mode == adapter->mode)		return dbus_message_new_method_return(msg);	err = set_mode(adapter, mode);	if (err < 0)		return failed_strerror(msg, -err);	return dbus_message_new_method_return(msg);}static DBusMessage *set_discoverable(DBusConnection *conn, DBusMessage *msg,				gboolean discoverable, void *data){	struct btd_adapter *adapter = data;	uint8_t mode;	int err;	mode = discoverable ? MODE_DISCOVERABLE : MODE_CONNECTABLE;	if (mode == MODE_DISCOVERABLE && adapter->pairable)		mode = MODE_LIMITED;	if (mode == adapter->mode)		return dbus_message_new_method_return(msg);	err = set_mode(adapter, mode);	if (err < 0)		return failed_strerror(msg, -err);	return dbus_message_new_method_return(msg);}static DBusMessage *set_pairable(DBusConnection *conn, DBusMessage *msg,				gboolean pairable, void *data){	struct btd_adapter *adapter = data;	uint8_t mode;	int err;	if (adapter->scan_mode == SCAN_DISABLED)		return adapter_not_ready(msg);	if (pairable == adapter->pairable)		goto done;	adapter->pairable = pairable;	write_device_pairable(&adapter->bdaddr, pairable);	emit_property_changed(connection, adapter->path,				ADAPTER_INTERFACE, "Pairable",				DBUS_TYPE_BOOLEAN, &pairable);	if (pairable && adapter->pairable_timeout)		adapter_set_pairable_timeout(adapter,						adapter->pairable_timeout);	if (!(adapter->scan_mode & SCAN_INQUIRY))		goto done;	mode = pairable ? MODE_LIMITED : MODE_DISCOVERABLE;	err = set_mode(adapter, mode);	if (err < 0 && msg)		return failed_strerror(msg, -err);done:	return msg ? dbus_message_new_method_return(msg) : NULL;}static gboolean pairable_timeout_handler(void *data){	set_pairable(NULL, NULL, FALSE, data);	return FALSE;}static void adapter_set_pairable_timeout(struct btd_adapter *adapter,					guint interval){	if (adapter->pairable_timeout_id) {		g_source_remove(adapter->pairable_timeout_id);		adapter->pairable_timeout_id = 0;	}	if (interval == 0)		return;	adapter->pairable_timeout_id = g_timeout_add_seconds(interval,							pairable_timeout_handler,							adapter);}static struct session_req *find_session(GSList *list, const char *sender){	GSList *l;	for (l = list; l; l = l->next) {		struct session_req *req = l->data;		if (g_str_equal(req->owner, sender))			return req;	}	return NULL;}static uint8_t get_needed_mode(struct btd_adapter *adapter, uint8_t mode){	GSList *l;	if (adapter->global_mode > mode)		mode = adapter->global_mode;	for (l = adapter->mode_sessions; l; l = l->next) {		struct session_req *req = l->data;		if (req->mode > mode)			mode = req->mode;	}	return mode;}static void session_remove(struct session_req *req){	struct btd_adapter *adapter = req->adapter;	if (req->mode) {		uint8_t mode;		adapter->mode_sessions = g_slist_remove(adapter->mode_sessions,							req);		mode = get_needed_mode(adapter, adapter->global_mode);		if (mode == adapter->mode)			return;		debug("Switching to '%s' mode", mode2str(mode));		set_mode(adapter, mode);	} else {		adapter->disc_sessions = g_slist_remove(adapter->disc_sessions,							req);		if (adapter->disc_sessions)			return;		debug("Stopping discovery");		if (adapter->state & STD_INQUIRY)			cancel_discovery(adapter);		else if (adapter->scheduler_id)			g_source_remove(adapter->scheduler_id);		else			cancel_periodic_discovery(adapter);	}}static void session_free(struct session_req *req){	debug("%s session %p with %s deactivated",		req->mode ? "Mode" : "Discovery", req, req->owner);	if (req->id)		g_dbus_remove_watch(req->conn, req->id);	session_remove(req);	if (req->msg)		dbus_message_unref(req->msg);	if (req->conn)		dbus_connection_unref(req->conn);	g_free(req->owner);	g_free(req);}static void session_owner_exit(DBusConnection *conn, void *user_data){	struct session_req *req = user_data;	req->id = 0;	session_free(req);}static struct session_req *session_ref(struct session_req *req){	req->refcount++;	debug("session_ref(%p): ref=%d", req, req->refcount);	return req;}static void session_unref(struct session_req *req){	req->refcount--;	debug("session_unref(%p): ref=%d", req, req->refcount);	if (req->refcount)		return;	session_free(req);}static struct session_req *create_session(struct btd_adapter *adapter,					DBusConnection *conn, DBusMessage *msg,					uint8_t mode, GDBusWatchFunction cb){	struct session_req *req;	const char *sender = dbus_message_get_sender(msg);	req = g_new0(struct session_req, 1);	req->adapter = adapter;	req->conn = dbus_connection_ref(conn);	req->msg = dbus_message_ref(msg);	req->owner = g_strdup(dbus_message_get_sender(msg));	req->mode = mode;	if (cb)		req->id = g_dbus_add_disconnect_watch(conn, sender, cb, req,							NULL);	info("%s session %p with %s activated",		req->mode ? "Mode" : "Discovery", req, sender);	return session_ref(req);}static void confirm_mode_cb(struct agent *agent, DBusError *derr, void *data){	struct session_req *req = data;	int err;	DBusMessage *reply;	if (derr && dbus_error_is_set(derr)) {		reply = dbus_message_new_error(req->msg, derr->name,						derr->message);		g_dbus_send_message(req->conn, reply);		session_unref(req);		return;	}	err = set_mode(req->adapter, req->mode);	if (err < 0)		reply = failed_strerror(req->msg, -err);	else		reply = dbus_message_new_method_return(req->msg);	g_dbus_send_message(req->conn, reply);	dbus_message_unref(req->msg);	req->msg = NULL;	if (!find_session(req->adapter->mode_sessions, req->owner))		session_unref(req);}static DBusMessage *set_discoverable_timeout(DBusConnection *conn,							DBusMessage *msg,							uint32_t timeout,							void *data){	struct btd_adapter *adapter = data;	const char *path;	if (adapter->discov_timeout == timeout && timeout == 0)		return dbus_message_new_method_return(msg);	if (adapter->scan_mode & SCAN_INQUIRY)		adapter_set_discov_timeout(adapter, timeout);	adapter->discov_timeout = timeout;	write_discoverable_timeout(&adapter->bdaddr, timeout);	path = dbus_message_get_path(msg);	emit_property_changed(conn, path,				ADAPTER_INTERFACE, "DiscoverableTimeout",				DBUS_TYPE_UINT32, &timeout);	return dbus_message_new_method_return(msg);}static DBusMessage *set_pairable_timeout(DBusConnection *conn,						DBusMessage *msg,						uint32_t timeout,						void *data){	struct btd_adapter *adapter = data;	const char *path;	if (adapter->pairable_timeout == timeout && timeout == 0)		return dbus_message_new_method_return(msg);	if (adapter->pairable)		adapter_set_pairable_timeout(adapter, timeout);	adapter->pairable_timeout = timeout;	write_pairable_timeout(&adapter->bdaddr, timeout);	path = dbus_message_get_path(msg);	emit_property_changed(conn, path,				ADAPTER_INTERFACE, "PairableTimeout",				DBUS_TYPE_UINT32, &timeout);	return dbus_message_new_method_return(msg);}static void update_ext_inquiry_response(int dd, struct hci_dev *dev){	uint8_t fec = 0, data[240];	if (!(dev->features[6] & LMP_EXT_INQ))		return;	memset(data, 0, sizeof(data));	if (dev->ssp_mode > 0)		create_ext_inquiry_response((char *) dev->name, data);	if (hci_write_ext_inquiry_response(dd, fec, data,						HCI_REQ_TIMEOUT) < 0)		error("Can't write extended inquiry response: %s (%d)",						strerror(errno), errno);}static int adapter_set_name(struct btd_adapter *adapter, const char *name){	struct hci_dev *dev = &adapter->dev;	int dd, err;	write_local_name(&adapter->bdaddr, (char *) name);	if (!adapter->up)		return 0;	dd = hci_open_dev(adapter->dev_id);	if (dd < 0) {		err = -errno;		error("Can't open device hci%d: %s (%d)",					adapter->dev_id, strerror(err), err);		return err;	}	if (hci_write_local_name(dd, name, HCI_REQ_TIMEOUT) < 0) {		err = -errno;		error("Can't write name for hci%d: %s (%d)",					adapter->dev_id, strerror(err), err);		hci_close_dev(dd);		return err;	}	strncpy((char *) dev->name, name, 248);	update_ext_inquiry_response(dd, dev);	hci_close_dev(dd);	return 0;}static DBusMessage *set_name(DBusConnection *conn, DBusMessage *msg,					const char *name, void *data){	struct btd_adapter *adapter = data;	int ecode;	const char *path;	if (!g_utf8_validate(name, -1, NULL)) {		error("Name change failed: the supplied name isn't valid UTF-8");		return invalid_args(msg);	}	ecode = adapter_set_name(adapter, name);	if (ecode < 0)		return failed_strerror(msg, -ecode);	path = dbus_message_get_path(msg);	emit_property_changed(conn, path, ADAPTER_INTERFACE, "Name",				DBUS_TYPE_STRING, &name);	return dbus_message_new_method_return(msg);}static void reply_authentication_failure(struct bonding_request_info *bonding){	DBusMessage *reply;	int status;	status = bonding->hci_status ?			bonding->hci_status : HCI_AUTHENTICATION_FAILURE;	reply = new_authentication_return(bonding->msg, status);	if (reply)		g_dbus_send_message(bonding->conn, reply);}struct btd_device *adapter_find_device(struct btd_adapter *adapter, const char *dest){	struct btd_device *device;	GSList *l;	if (!adapter)		return NULL;	l = g_slist_find_custom(adapter->devices,				dest, (GCompareFunc) device_address_cmp);	if (!l)		return NULL;

⌨️ 快捷键说明

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