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

📄 device.c

📁 这是Linux环境下的蓝牙源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
	address_up = g_ascii_strup(address, -1);	device->path = g_strdup_printf("%s/hci%d/dev_%s", "/org/bluez",							dev_id, 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;	}	device->address = g_strdup(address);	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(driver, 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){	return strcasecmp(device->address, address);}sdp_record_t *get_record(sdp_list_t *recs, const char *uuid){	sdp_list_t *seq;	for (seq = recs; seq; seq = seq->next) {		sdp_record_t *rec = (sdp_record_t *) seq->data;		sdp_list_t *svcclass = NULL;		char *uuid_str;		if (sdp_get_service_classes(rec, &svcclass) < 0)			continue;		/* Extract the uuid */		uuid_str = bt_uuid2string(svcclass->data);		if (!uuid_str)			continue;		if (!strcasecmp(uuid_str, uuid)) {			sdp_list_free(svcclass, free);			free(uuid_str);			return rec;		}		sdp_list_free(svcclass, free);		free(uuid_str);	}	return NULL;}void device_probe_drivers(struct btd_device *device, GSList *uuids, sdp_list_t *recs){	GSList *list = btd_get_device_drivers();	const char **uuid;	int err;	debug("Probe drivers for %s", device->path);	for (; list; list = list->next) {		struct btd_device_driver *driver = list->data;		GSList *records = NULL;		for (uuid = driver->uuids; *uuid; uuid++) {			sdp_record_t *rec;			if (!g_slist_find_custom(uuids, *uuid,					(GCompareFunc) strcasecmp))				continue;			rec = get_record(recs, *uuid);			if (!rec)				continue;			records = g_slist_append(records, rec);		}		if (records) {			struct btd_driver_data *driver_data = g_new0(struct btd_driver_data, 1);			err = driver->probe(driver, device, records);			if (err < 0) {				error("probe failed for driver %s",							driver->name);				g_free(driver_data);				continue;			}			driver_data->driver = driver;			device->drivers = g_slist_append(device->drivers,								driver_data);		}	}	for (list = uuids; list; list = list->next)		device->uuids = g_slist_insert_sorted(device->uuids,				list->data, (GCompareFunc) strcmp);}void device_remove_drivers(struct btd_device *device, GSList *uuids, sdp_list_t *recs){	struct adapter *adapter = device_get_adapter(device);	const gchar *src = adapter_get_address(adapter);	const gchar *dst = device_get_address(device);	GSList *list;	debug("Remove drivers for %s", device->path);	for (list = device->drivers; list; list = list->next) {		struct btd_driver_data *driver_data = list->data;		struct btd_device_driver *driver = driver_data->driver;		const char **uuid;		for (uuid = driver->uuids; *uuid; uuid++) {			sdp_record_t *rec;			if (!g_slist_find_custom(uuids, *uuid,					(GCompareFunc) strcasecmp))				continue;			driver->remove(driver, device);			device->drivers = g_slist_remove(device->drivers,								driver_data);			g_free(driver_data);			rec = get_record(recs, *uuid);			if (!rec)				continue;			delete_record(src, dst, rec->handle);		}	}	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);}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);	dbus_connection_send(req->conn, reply, NULL);	dbus_message_unref(reply);}static void services_changed(struct browse_req *req){	struct btd_device *device = req->device;	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;	dbus_connection_emit_property_changed(req->conn, device->path,					DEVICE_INTERFACE, "UUIDs",					DBUS_TYPE_ARRAY, &uuids);	g_free(uuids);}static void update_services(struct browse_req *req, sdp_list_t *recs){	struct btd_device *device = req->device;	struct adapter *adapter = device_get_adapter(device);	const gchar *src = adapter_get_address(adapter);	const gchar *dst = device_get_address(device);	sdp_list_t *seq;	for (seq = recs; seq; seq = seq->next) {		sdp_record_t *rec = (sdp_record_t *) seq->data;		sdp_list_t *svcclass = NULL;		gchar *uuid_str;		GSList *l;		if (!rec)			break;		if (sdp_get_service_classes(rec, &svcclass) < 0)			continue;		store_record(src, dst, rec);		/* Extract the first element and skip the remainning */		uuid_str = bt_uuid2string(svcclass->data);		if (!uuid_str)			continue;		l = g_slist_find_custom(device->uuids, uuid_str,				(GCompareFunc) strcmp);		if (!l)			req->uuids_added = g_slist_append(req->uuids_added,					uuid_str);		else {			req->uuids_removed = g_slist_remove(req->uuids_removed,					l->data);			g_free(uuid_str);		}		sdp_list_free(svcclass, free);	}}static void store(struct btd_device *device){	struct adapter *adapter = device->adapter;	bdaddr_t src, dst;	char *str;	const gchar *source = adapter_get_address(adapter);	str2ba(source, &src);	str2ba(device->address, &dst);	if (!device->uuids) {		write_device_profiles(&src, &dst, "");		return;	}	str = bt_list2string(device->uuids);	write_device_profiles(&src, &dst, str);	g_free(str);}static void browse_cb(sdp_list_t *recs, int err, gpointer user_data){	struct browse_req *req = user_data;	struct btd_device *device = req->device;	struct adapter *adapter = device->adapter;	bdaddr_t src, dst;	uuid_t uuid;	DBusMessage *reply;	const gchar *source = adapter_get_address(adapter);	if (err < 0)		goto proceed;	update_services(req, recs);	/* Public browsing successful or Single record requested */	if (req->browse == FALSE || (!req->search_uuid && recs))		goto probe;	if (uuid_list[++req->search_uuid]) {		sdp_uuid16_create(&uuid, uuid_list[req->search_uuid]);		str2ba(source, &src);		str2ba(device->address, &dst);		bt_search_service(&src, &dst, &uuid, browse_cb, user_data, NULL);		return;	}probe:	if (!req->uuids_added && !req->uuids_removed)		goto proceed;	/* Probe matching drivers for services added */	if (req->uuids_added)		device_probe_drivers(device, req->uuids_added, recs);	/* Remove drivers for services removed */	if (req->uuids_removed)		device_remove_drivers(device, req->uuids_removed, recs);	/* Store the device's profiles in the filesystem */	store(device);	/* Propagate services changes */	services_changed(req);proceed:	if (dbus_message_is_method_call(req->msg, DEVICE_INTERFACE,			"DiscoverServices")) {		discover_device_reply(req, recs);		goto cleanup;	}	g_dbus_emit_signal(req->conn, dbus_message_get_path(req->msg),				ADAPTER_INTERFACE, "DeviceCreated",				DBUS_TYPE_OBJECT_PATH, &device->path,				DBUS_TYPE_INVALID);	/* Reply create device request */	reply = dbus_message_new_method_return(req->msg);	if (!reply)		goto cleanup;	dbus_message_append_args(reply, DBUS_TYPE_OBJECT_PATH, &device->path,							DBUS_TYPE_INVALID);	dbus_connection_send(req->conn, reply, NULL);	dbus_message_unref(reply);cleanup:	device->discov_active = 0;	if (device->discov_requestor) {		g_dbus_remove_watch(req->conn, device->discov_listener);		device->discov_listener = 0;		g_free(device->discov_requestor);		device->discov_requestor = NULL;	}	if (recs != NULL)		sdp_list_free(recs, (sdp_free_func_t) sdp_record_free);	dbus_message_unref(req->msg);	dbus_connection_unref(req->conn);	g_slist_free(req->uuids_added);	g_slist_free(req->uuids_removed);	g_free(req);}int device_browse(struct btd_device *device, DBusConnection *conn,			DBusMessage *msg, uuid_t *search){	struct adapter *adapter = device->adapter;	struct browse_req *req;	bdaddr_t src, dst;	uuid_t uuid;	GSList *l;	const gchar *source = adapter_get_address(adapter);	req = g_new0(struct browse_req, 1);	req->conn = dbus_connection_ref(conn);	req->msg = dbus_message_ref(msg);	req->device = device;	str2ba(source, &src);	str2ba(device->address, &dst);	if (search) {		memcpy(&uuid, search, sizeof(uuid_t));		req->browse = FALSE;	} else {		sdp_uuid16_create(&uuid, uuid_list[req->search_uuid]);		req->browse = TRUE;		for (l = device->uuids; l; l = l->next)			req->uuids_removed = g_slist_append(req->uuids_removed,						l->data);	}	device->discov_active = 1;	device->discov_requestor = g_strdup(dbus_message_get_sender(msg));	/* Track the request owner to cancel it	 * automatically if the owner exits */	device->discov_listener = g_dbus_add_disconnect_watch(conn,						dbus_message_get_sender(msg),						discover_services_req_exit,						device, NULL);	return bt_search_service(&src, &dst, &uuid, browse_cb, req, NULL);}struct adapter *device_get_adapter(struct btd_device *device){	if (!device)		return NULL;	return device->adapter;}const gchar *device_get_address(struct btd_device *device){	if (!device)		return NULL;	return device->address;}const gchar *device_get_path(struct btd_device *device){	if (!device)		return NULL;	return device->path;}struct agent *device_get_agent(struct btd_device *device){	if (!device)		return NULL;	return  device->agent;}void device_set_agent(struct btd_device *device, struct agent *agent){	if (!device)		return;	device->agent = agent;}gboolean device_is_busy(struct btd_device *device){	return device->discov_active ? TRUE : FALSE;}gboolean device_is_temporary(struct btd_device *device){	return device->temporary;}void device_set_temporary(struct btd_device *device, gboolean temporary){	if (!device)		return;	device->temporary = temporary;}void device_set_cap(struct btd_device *device, uint8_t cap){	if (!device)		return;	device->cap = cap;}void device_set_auth(struct btd_device *device, uint8_t auth){	if (!device)		return;	device->auth = auth;}uint8_t device_get_auth(struct btd_device *device){	return device->auth;}

⌨️ 快捷键说明

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