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

📄 device.c

📁 BlueZ源码
💻 C
📖 第 1 页 / 共 3 页
字号:
		return FALSE;	dd = hci_open_dev(dev_id);	if (dd < 0)		goto fail;	memset(&cp, 0, sizeof(cp));	cp.handle = htobs(ci->handle);	cp.reason = HCI_OE_USER_ENDED_CONNECTION;	hci_send_cmd(dd, OGF_LINK_CTL, OCF_DISCONNECT,			DISCONNECT_CP_SIZE, &cp);	close(dd);fail:	return FALSE;}static DBusMessage *disconnect(DBusConnection *conn,					DBusMessage *msg, void *user_data){	struct btd_device *device = user_data;	struct active_conn_info *dev;	dev = adapter_search_active_conn_by_bdaddr(device->adapter,							&device->bdaddr);	if (!dev)		return g_dbus_create_error(msg,				ERROR_INTERFACE ".NotConnected",				"Device is not connected");	g_dbus_emit_signal(conn, device->path,			DEVICE_INTERFACE, "DisconnectRequested",			DBUS_TYPE_INVALID);	device->disconn_timer = g_timeout_add_seconds(DISCONNECT_TIMER,						disconnect_timeout, device);	return dbus_message_new_method_return(msg);}static GDBusMethodTable device_methods[] = {	{ "GetProperties",	"",	"a{sv}",	get_properties	},	{ "SetProperty",	"sv",	"",		set_property	},	{ "DiscoverServices",	"s",	"a{us}",	discover_services,						G_DBUS_METHOD_FLAG_ASYNC},	{ "CancelDiscovery",	"",	"",		cancel_discover	},	{ "Disconnect",		"",	"",		disconnect	},	{ }};static GDBusSignalTable device_signals[] = {	{ "PropertyChanged",		"sv"	},	{ "DisconnectRequested",	""	},	{ }};gboolean device_get_connected(struct btd_device *device){	return device->connected;}void device_set_connected(DBusConnection *conn, struct btd_device *device,			gboolean connected){	device->connected = connected;	emit_property_changed(conn, device->path, DEVICE_INTERFACE,				"Connected", DBUS_TYPE_BOOLEAN, &connected);	if (connected && device->secmode3) {		struct btd_adapter *adapter = device_get_adapter(device);		bdaddr_t sba;		adapter_get_address(adapter, &sba);		device->secmode3 = FALSE;		hcid_dbus_bonding_process_complete(&sba, &device->bdaddr, 0);	}}void device_set_secmode3_conn(struct btd_device *device, gboolean enable){	device->secmode3 = enable;}struct btd_device *device_create(DBusConnection *conn, struct btd_adapter *adapter,					const gchar *address){	gchar *address_up;	struct btd_device *device;	const gchar *adapter_path = adapter_get_path(adapter);	device = g_try_malloc0(sizeof(struct btd_device));	if (device == NULL)		return NULL;	address_up = g_ascii_strup(address, -1);	device->path = g_strdup_printf("%s/dev_%s", adapter_path, address_up);	g_strdelimit(device->path, ":", '_');	g_free(address_up);	debug("Creating device %s", device->path);	if (g_dbus_register_interface(conn, device->path, DEVICE_INTERFACE,				device_methods, device_signals, NULL,				device, device_free) == FALSE) {		device_free(device);		return NULL;	}	str2ba(address, &device->bdaddr);	device->adapter = adapter;	return device;}void device_remove(DBusConnection *conn, struct btd_device *device){	GSList *list;	struct btd_device_driver *driver;	gchar *path = g_strdup(device->path);	debug("Removing device %s", path);	for (list = device->drivers; list; list = list->next) {		struct btd_driver_data *driver_data = list->data;		driver = driver_data->driver;		driver->remove(device);		g_free(driver_data);	}	g_dbus_unregister_interface(conn, path, DEVICE_INTERFACE);	g_free(path);}gint device_address_cmp(struct btd_device *device, const gchar *address){	char addr[18];	ba2str(&device->bdaddr, addr);	return strcasecmp(addr, address);}static gboolean record_has_uuid(const sdp_record_t *rec,				const char *profile_uuid){	sdp_list_t *pat;	for (pat = rec->pattern; pat != NULL; pat = pat->next) {		char *uuid;		int ret;		uuid = bt_uuid2string(pat->data);		if (!uuid)			continue;		ret = strcasecmp(uuid, profile_uuid);		g_free(uuid);		if (ret == 0)			return TRUE;	}	return FALSE;}static GSList *device_match_pattern(struct btd_device *device,					const char *match_uuid,					GSList *profiles){	GSList *l, *uuids = NULL;	for (l = profiles; l; l = l->next) {		char *profile_uuid = l->data;		const sdp_record_t *rec;		rec = btd_device_get_record(device, profile_uuid);		if (!rec)			continue;		if (record_has_uuid(rec, match_uuid))			uuids = g_slist_append(uuids, profile_uuid);	}	return uuids;}static GSList *device_match_driver(struct btd_device *device,					struct btd_device_driver *driver,					GSList *profiles){	const char **uuid;	GSList *uuids = NULL;	for (uuid = driver->uuids; *uuid; uuid++) {		GSList *match;		/* skip duplicated uuids */		if (g_slist_find_custom(uuids, *uuid,				(GCompareFunc) strcasecmp))			continue;		/* match profile driver */		match = g_slist_find_custom(profiles, *uuid,					(GCompareFunc) strcasecmp);		if (match) {			uuids = g_slist_append(uuids, match->data);			continue;		}		/* match pattern driver */		match = device_match_pattern(device, *uuid, profiles);		for (; match; match = match->next)			uuids = g_slist_append(uuids, match->data);	}	return uuids;}void device_probe_drivers(struct btd_device *device, GSList *profiles){	GSList *list;	int err;	debug("Probe drivers for %s", device->path);	for (list = device_drivers; list; list = list->next) {		struct btd_device_driver *driver = list->data;		GSList *probe_uuids;		struct btd_driver_data *driver_data;		probe_uuids = device_match_driver(device, driver, profiles);		if (!probe_uuids)			continue;		driver_data = g_new0(struct btd_driver_data, 1);		err = driver->probe(device, probe_uuids);		if (err < 0) {			error("probe failed with driver %s for device %s",					driver->name, device->path);			g_free(driver_data);			g_slist_free(probe_uuids);			continue;		}		driver_data->driver = driver;		device->drivers = g_slist_append(device->drivers, driver_data);		g_slist_free(probe_uuids);	}	for (list = profiles; list; list = list->next) {		GSList *l = g_slist_find_custom(device->uuids, list->data,							(GCompareFunc) strcasecmp);		if (l)			continue;		device->uuids = g_slist_insert_sorted(device->uuids,							g_strdup(list->data),							(GCompareFunc) strcasecmp);	}	if (device->tmp_records) {		sdp_list_free(device->tmp_records,				(sdp_free_func_t) sdp_record_free);		device->tmp_records = NULL;	}}void device_remove_drivers(struct btd_device *device, GSList *uuids){	struct btd_adapter *adapter = device_get_adapter(device);	GSList *list, *next;	char srcaddr[18], dstaddr[18];	bdaddr_t src;	sdp_list_t *records;	adapter_get_address(adapter, &src);	ba2str(&src, srcaddr);	ba2str(&device->bdaddr, dstaddr);	records = read_records(&src, &device->bdaddr);	debug("Remove drivers for %s", device->path);	for (list = device->drivers; list; list = next) {		struct btd_driver_data *driver_data = list->data;		struct btd_device_driver *driver = driver_data->driver;		const char **uuid;		next = list->next;		for (uuid = driver->uuids; *uuid; uuid++) {			sdp_record_t *rec;			if (!g_slist_find_custom(uuids, *uuid,					(GCompareFunc) strcasecmp))				continue;			debug("UUID %s was removed from device %s", *uuid, dstaddr);			driver->remove(device);			device->drivers = g_slist_remove(device->drivers,								driver_data);			g_free(driver_data);			rec = find_record_in_list(records, *uuid);			if (!rec)				break;			delete_record(srcaddr, dstaddr, rec->handle);			records = sdp_list_remove(records, rec);			sdp_record_free(rec);			break;		}	}	if (records)		sdp_list_free(records, (sdp_free_func_t) sdp_record_free);	for (list = uuids; list; list = list->next)		device->uuids = g_slist_remove(device->uuids, list->data);}static void iter_append_record(DBusMessageIter *dict, uint32_t handle,							const char *record){	DBusMessageIter entry;	dbus_message_iter_open_container(dict, DBUS_TYPE_DICT_ENTRY,							NULL, &entry);	dbus_message_iter_append_basic(&entry, DBUS_TYPE_UINT32, &handle);	dbus_message_iter_append_basic(&entry, DBUS_TYPE_STRING, &record);	dbus_message_iter_close_container(dict, &entry);}static void append_and_grow_string(void *data, const char *str){	sdp_buf_t *buff = data;	int len;	len = strlen(str);	if (!buff->data) {		buff->data = malloc(DEFAULT_XML_BUF_SIZE);		if (!buff->data)			return;		buff->buf_size = DEFAULT_XML_BUF_SIZE;	}	/* Grow string */	while (buff->buf_size < (buff->data_size + len + 1)) {		void *tmp;		uint32_t new_size;		/* Grow buffer by a factor of 2 */		new_size = (buff->buf_size << 1);		tmp = realloc(buff->data, new_size);		if (!tmp)			return;		buff->data = tmp;		buff->buf_size = new_size;	}	/* Include the NULL character */	memcpy(buff->data + buff->data_size, str, len + 1);	buff->data_size += len;}static void discover_device_reply(struct browse_req *req, sdp_list_t *recs){	DBusMessage *reply;	DBusMessageIter iter, dict;	sdp_list_t *seq;	reply = dbus_message_new_method_return(req->msg);	if (!reply)		return;	dbus_message_iter_init_append(reply, &iter);	dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY,			DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING			DBUS_TYPE_UINT32_AS_STRING DBUS_TYPE_STRING_AS_STRING			DBUS_DICT_ENTRY_END_CHAR_AS_STRING, &dict);	for (seq = recs; seq; seq = seq->next) {		sdp_record_t *rec = (sdp_record_t *) seq->data;		sdp_buf_t result;		if (!rec)			break;		memset(&result, 0, sizeof(sdp_buf_t));		convert_sdp_record_to_xml(rec, &result,				append_and_grow_string);		if (result.data) {			const char *val = (char *) result.data;			iter_append_record(&dict, rec->handle, val);			free(result.data);		}	}	dbus_message_iter_close_container(&iter, &dict);	g_dbus_send_message(req->conn, reply);}static void services_changed(struct btd_device *device){	DBusConnection *conn = get_dbus_connection();	char **uuids;	GSList *l;	int i;	uuids = g_new0(char *, g_slist_length(device->uuids) + 1);	for (i = 0, l = device->uuids; l; l = l->next, i++)		uuids[i] = l->data;	emit_array_property_changed(conn, device->path, DEVICE_INTERFACE,					"UUIDs", DBUS_TYPE_STRING, &uuids);	g_free(uuids);}static int rec_cmp(const void *a, const void *b){	const sdp_record_t *r1 = a;	const sdp_record_t *r2 = b;	return r1->handle - r2->handle;}static void update_services(struct browse_req *req, sdp_list_t *recs){	struct btd_device *device = req->device;

⌨️ 快捷键说明

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